random_int_expr_mutation(Node,Mutation) :-
prob_is_ground(Node,true) ,
replace_ground_with_expr(Node,Mutation).
random_int_expr_mutation(b(Expression,integer,Info),b(NewExpression,integer,Info)) :-
Expression =.. [Type,Expr1,Expr2] ,
member(Type,[add,minus,multiplication,div,modulo,power_of]) ,
% random choice heuristic for argument
random(0,3,R) ,
% if expression is ground replace its value by an arithmetic expression
( R = 0 ->
(prob_is_ground(Expr1,true) ->
replace_ground_with_expr(Expr1,NewExpr1)
; random_int_expr_mutation(Expr1,NewExpr1)) ,
NewExpr2 = Expr2
; R = 1 ->
(prob_is_ground(Expr2,true) ->
replace_ground_with_expr(Expr2,NewExpr2)
; random_int_expr_mutation(Expr2,NewExpr2)) ,
NewExpr1 = Expr1
; % try replacing both arguments with expressions
(prob_is_ground(Expr1,true) ->
replace_ground_with_expr(Expr1,NewExpr1)
; random_int_expr_mutation(Expr1,NewExpr1)) ,
(prob_is_ground(Expr2,true) ->
replace_ground_with_expr(Expr2,NewExpr2)
; random_int_expr_mutation(Expr2,NewExpr2))) ,
NewExpression =.. [Type,NewExpr1,NewExpr2].
random_int_expr_mutation(b(Expression,integer,Info),b(NewExpression,integer,Info)) :-
Expression =.. [Type,Expr1,Expr2] ,
random_int_expr_mutation(Expr1,NewExpr1) ,
random_int_expr_mutation(Expr2,NewExpr2) ,
NewExpression =.. [Type,NewExpr1,NewExpr2].
random_int_expr_mutation(b(Expression,integer,Info),b(NewExpression,integer,Info)) :-
Expression =.. [Type,Expr] ,
\+member(Type,[max,min]) ,
(prob_is_ground(Expr,true) ->
replace_ground_with_expr(Expr,NewExpr)
; random_int_expr_mutation(Expr,NewExpr)) ,
NewExpression =.. [Type,NewExpr].
random_int_expr_mutation(Expression,Expression).