JuliaServices / Match.jl

Advanced Pattern Matching for Julia
https://juliaservices.github.io/Match.jl/latest/
Other
240 stars 22 forks source link

Add an optimization to remove a value test after a type test that shows that the input is not of the type. #88

Open gafter opened 1 year ago

gafter commented 1 year ago

See this part of an automaton:

Node 33
  5: («input_value» isa Tuple && «length(input_value)» := length(«input_value») && «length(input_value)» >= 2 && «input_value[-1]» := «input_value»[-1] && «where_0» := e.q1 && «where_0») => [z => «input_value[-1]»] z
  6: (@ismatch(6, «input_value») || @ismatch(7, «input_value»)) => 6
  7: («input_value» isa Main.Rematch2Tests.A && «where_1» := e.q2 && «where_1») => 7
  8: («input_value» isa Main.Rematch2Tests.B && «where_2» := e.q3 && «where_2») => 8
  9: («input_value» isa Main.Rematch2Tests.C && «where_3» := e.q4 && «where_3») => 9
    TEST «input_value» isa Tuple
    THEN: Node 34 (fall through)
    ELSE: Node 42
Node 34
  5: («length(input_value)» := length(«input_value») && «length(input_value)» >= 2 && «input_value[-1]» := «input_value»[-1] && «where_0» := e.q1 && «where_0») => [z => «input_value[-1]»] z
  6: (@ismatch(6, «input_value») || @ismatch(7, «input_value»)) => 6
    FETCH «length(input_value)» := length(«input_value»)
    NEXT: Node 35 (fall through)

After determining that the input is a Tuple in node 33, we should eliminate the possibility that its value is 6 or 7, because those aren't values of tuple type.

Similarly, if we had discovered that its value is not of type Int, we should also eliminate the possibility of 6 or 7.

Be careful with a pattern that is a regular expression (which matches values of type AbstractString) or by equality to another regular expression, or an AbstractRange which matches range elements using ==, so for example 2.0 occursin 1:3. We may need to drop this optimization for any type that has a specialized implementation of ismatch. Also be careful about other specializations of isequal and ==. For example, a substring can test isequal to a string.