<commit_before>-module(mu2_case_mutations).

-export([all/0, case_mutations/0, random_not_n/2, swap/3]).

-include("../include/mutations.hrl").

-compile(nowarn_shadow_vars).

all() ->
    case_mutations().

all_constant(P) ->
    case api_refac:type(P) of
	atom ->
	    true;
	underscore ->
	    true;
	integer ->
	    true;
	tuple ->
	    {tree,tuple,_Attrs,Content} = P,
	    length(lists:filter(fun all_constant/1,Content)) == length(Content);
	variable ->
	    false;
	list ->
	    false;
	nil ->
	    true;
	_ ->
	    false
    end.

is_valid_pattern(Ps) ->
    %% We must have no all-constant entries
    length(lists:filter(fun all_constant/1,Ps)) == 0.

is_valid_pattern_set(Pats@@@) ->
    if length(Pats@@@) > 1 ->
	    %% We need at least non-constant patterns
	    length(lists:filter(fun is_valid_pattern/1, Pats@@@)) > 1;
       true ->
	    false
    end.


case_mutations() ->
    [{swap_case_order,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 is_valid_pattern_set(Pats@@@)
			),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
		    A = random:uniform(length(Pats@@@)),
		    B = random_not_n(length(Pats@@@), A),
		    NewPats@@@ = swap(Pats@@@, A, B),
		    NewGuards@@@ = swap(Guards@@@, A, B),
		    NewBody@@@ = swap(Body@@@, A, B),
		    ?TO_AST("case Expr@ of NewPats@@@ when NewGuards@@@ -> NewBody@@@ end")
		end)},
     {exchange_case_guard,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 (length(Pats@@@) > 1) and (lists:flatten(lists:map(fun api_refac:exported_vars/1, Pats@@@)) == [])),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
		    A = random:uniform(length(Pats@@@)),
		    B = random_not_n(length(Pats@@@), A),
		    NewGuards@@@ = swap(Guards@@@, A, B),
		    ?TO_AST("case Expr@ of Pats@@@ when NewGuards@@@-> Body@@@ end")
		end)},
     {exchange_case_pattern,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 (length(Pats@@@) > 1) and (lists:flatten(lists:map(fun api_refac:exported_vars/1, Pats@@@)) == [])),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
		    A = random:uniform(length(Pats@@@)),
		    B = random_not_n(length(Pats@@@), A),
		    NewPats@@@ = swap(Pats@@@, A, B),
		    ?TO_AST("case Expr@ of NewPats@@@ when Guards@@@-> Body@@@ end")
		end)},
     {remove_last_case,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 length(Pats@@@) > 1),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin<commit_msg>Only exchange case guards if they aren't blank...<commit_after>-module(mu2_case_mutations).

-export([all/0, case_mutations/0, random_not_n/2, swap/3]).

-include("../include/mutations.hrl").

-compile(nowarn_shadow_vars).

all() ->
    case_mutations().

all_constant(P) ->
    case api_refac:type(P) of
	atom ->
	    true;
	underscore ->
	    true;
	integer ->
	    true;
	tuple ->
	    {tree,tuple,_Attrs,Content} = P,
	    length(lists:filter(fun all_constant/1,Content)) == length(Content);
	variable ->
	    false;
	list ->
	    false;
	nil ->
	    true;
	_ ->
	    false
    end.

is_valid_pattern(Ps) ->
    %% We must have no all-constant entries
    length(lists:filter(fun all_constant/1,Ps)) == 0.

is_valid_pattern_set(Pats@@@) ->
    if length(Pats@@@) > 1 ->
	    %% We need at least non-constant patterns
	    length(lists:filter(fun is_valid_pattern/1, Pats@@@)) > 1;
       true ->
	    false
    end.


case_mutations() ->
    [{swap_case_order,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 is_valid_pattern_set(Pats@@@)
			),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
		    A = random:uniform(length(Pats@@@)),
		    B = random_not_n(length(Pats@@@), A),
		    NewPats@@@ = swap(Pats@@@, A, B),
		    NewGuards@@@ = swap(Guards@@@, A, B),
		    NewBody@@@ = swap(Body@@@, A, B),
		    ?TO_AST("case Expr@ of NewPats@@@ when NewGuards@@@ -> NewBody@@@ end")
		end)},
     {exchange_case_guard,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 (length(Pats@@@) > 1) 
			 and (lists:flatten(lists:map(fun api_refac:exported_vars/1, Pats@@@)) == [])
			 and (lists:flatten(lists:filter(fun(G) -> length(G) > 0 end, Guards@@@)))
			),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
		    A = random:uniform(length(Pats@@@)),
		    B = random_not_n(length(Pats@@@), A),
		    NewGuards@@@ = swap(Guards@@@, A, B),
		    ?TO_AST("case Expr@ of Pats@@@ when NewGuards@@@-> Body@@@ end")
		end)},
     {exchange_case_pattern,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 (length(Pats@@@) > 1) and (lists:flatten(lists:map(fun api_refac:exported_vars/1, Pats@@@)) == [])),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
		    A = random:uniform(length(Pats@@@)),
		    B = random_not_n(length(Pats@@@), A),
		    NewPats@@@ = swap(Pats@@@, A, B),
		    ?TO_AST("case Expr@ of NewPats@@@ when Guards@@@-> Body@@@ end")
		end)},
     {remove_last_case,
      ?MUTATION_RESTRICT("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
			 length(Pats@@@) > 1),
      ?MUTATION("case Expr@ of Pats@@@ when Guards@@@ -> Body@@@ end",
		begin
{'fraction_non_alphanumeric': 0.20481927710843373, 'fraction_numerical': 0.0061167747914735865, 'mean_word_length': 3.306464485235435, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3798733', 'n_tokens_mistral': 2250, 'n_tokens_neox': 2064, 'n_words': 432}