expressions(b(identifier(op(_)), Type, _), b(identifier(op(_)), Type, _), Before, Before) :- !.
expressions(b(identifier(Val), Type, _), b(identifier(PVal), Type, _), Before, After) :- !,
(lookup(Val, Before, PVal)-> After=Before; insert(Val, PVal, Before, After)).
expressions(b(identifier(Val)), b(identifier(PVal)), Before, After) :- !,
(lookup(Val, Before, PVal)-> After=Before; insert(Val, PVal, Before, After)).
expressions(b(unary_minus(Exp), Type,_), b(unary_minus(PExp), Type,_), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(integer(Val), Type, _ ), b(integer(Val), Type, _), Before, Before ) :- !.
expressions(b(boolean_false, Type, _), b(boolean_false, Type, _), Before, Before).
expressions(b(boolean_true, Type, _), b(boolean_true, Type, _), Before, Before).
expressions(b(min_int, Type, _), b(min_int, Type, _), Before, Before).
expressions(b(max_int, Type, _), b(max_int, Type, _), Before, Before).
expressions(b(integer_set(Var), Type, _), b(integer_set(Var), Type, _), Before, Before).
expressions(b(interval(A, B), Type, [was(integer_set('NAT')),_]),
b(interval(NewA, NewB), Type, [was(integer_set('NAT')),_]), Before, Before) :-
expressions(A, NewA, _,_),
expressions(B, NewB, _,_).
expressions(b(interval(A, B), Type, [was(integer_set('INT')),_]),
b(interval(NewA, NewB), Type, [was(integer_set('INT')),_]), Before, Before) :-
expressions(A, NewA, _,_),
expressions(B, NewB, _,_).
expressions(b(bool_set,Type,_), b(bool_set,Type,_), Before, Before).
expressions(b(set_extension(SetElements), Type, _), b(set_extension(PSetElements), Type, _), Before, After) :-
process_all_expressions(SetElements, PSetElements, Before, After).
expressions(b(relations(Left, Right), Type, _), b(relations(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(couple(Left, Right), Type , _), b(couple(PLeft, PRight), Type , _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(union(Left, Right), Type, Info), b(union(PLeft, PRight), Type, Info), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(event_b_identity, _, _), b(event_b_identity, _, _), Before, Before).
expressions(b(total_function(From, To), Type, _), b(total_function(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(partial_function(From, To), Type, _), b(partial_function(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(total_injection(From, To), Type, _), b(total_injection(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(partial_injection(From, To), Type, _), b(partial_injection(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(total_surjection(From, To), Type, _), b(total_surjection(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(partial_surjection(From, To), Type, _), b(partial_surjection(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(total_bijection(From, To), Type, _), b(total_bijection(PFrom, PTo), Type, _), Before, After) :-
handle_binary_exp(From, To, PFrom, PTo, Before, After).
expressions(b(partial_bijection(Left, Right), Type, _), b(partial_bijection(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(interval(Left, Right), Type, _), b(interval(PLeft, PRight), Type, _), Before,After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(add(Left, Right), Type, _), b(add(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(minus(Left, Right), Type, _), b(minus(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(Left div Right, Type, _), b(PLeft div PRight, Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(multiplication(Left, Right), Type, _), b(multiplication(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(modulo(Left, Right), Type, _), b(modulo(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(set_subtraction(Left, Right), Type, _), b(set_subtraction(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(intersection(Left, Right), Type, _), b(intersection(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(direct_product(Left, Right), Type, _), b(direct_product(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(composition(Left,Right), Type, _), b(composition(PLeft,PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(cartesian_product(Left, Right), Type, _), b(cartesian_product(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(concat(Left, Right), Type, _), b(concat(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(domain_restriction(Left, Right), Type, _), b(domain_restriction(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(domain_subtraction(Left, Right), Type, _), b(domain_subtraction(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(range_restriction(Left, Right), Type, _), b(range_restriction(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(range_subtraction(Left, Right), Type, _), b(range_subtraction(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(restrict_tail(Left, Right), Type, _), b(restrict_tail(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(restrict_front(Left, Right), Type, _), b(restrict_front(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(function(Left, Right), Type, _), b(function(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(overwrite(Left, Right), Type, _), b(overwrite(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(parallel_product(Left, Right), Type, _), b(parallel_product(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(image(Left, Right), Type, _), b(image(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(first_of_pair(Exp), _, _), b(first_of_pair(PExp), _, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(second_of_pair(Exp), _, _), b(first_of_pair(PExp), _, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(iteration(Left, Right), Type, _), b(iteration(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Right, PLeft, PRight, Before, After).
expressions(b(range(Exp), Type, _), b(range(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(domain(Exp), Type, _), b(domain(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(card(Exp), Type, _), b(card(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(reflexive_closure(Exp), Type, _), b(reflexive_closure(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(closure(Exp), Type, _), b(closure(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(min(Exp), Type, _), b(min(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(max(Exp), Type, _), b(max(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(pow_subset(Exp), Type, _), b(pow_subset(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(pow1_subset(Exp), Type, _), b(pow1_subset(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(fin_subset(Exp), Type, _), b(fin_subset(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(fin1_subset(Exp), Type, _), b(fin1_subset(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(general_concat(Exp), Type, _), b(general_concat(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(first(Exp), Type, _), b(first(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(last(Exp), Type, _), b(last(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(front(Exp), Type, _), b(front(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(tail(Exp), Type, _), b(tail(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(identity(Exp), Type, _), b(identity(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(reverse(Exp), Type, _), b(reverse(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(rev(Exp), Type, _), b(rev(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(size(Exp), Type, _), b(size(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(convert_bool(Pred), Type, _), b(convert_bool(PPred), Type, _), Before, After) :-
predicates(Pred, PPred, Before, After).
expressions(b(let_expression(Variables, SubValues, Expression), Type, _), b(let_expression(PVariables, PSubValues, PExpression), Type, _), Before, After) :-
process_all_expressions(Variables, PVariables, [], LetAfter),
append(Before, LetAfter, BeforeWithLet),
process_all_predicates(SubValues, PSubValues, BeforeWithLet, After1),
expressions(Expression, PExpression, After1, After2),
keys_and_values(LetAfter, LetKeys,_),
maplist(remove_key, LetKeys, After2, After).
expressions(b(empty_set, Type, _), b(empty_set, Type, _), Before, Before).
expressions(b(empty_sequence, seq(Type), _), b(empty_sequence, seq(Type), _), Before, Before).
expressions(b(surjection_relation(S, T), Type, _), b(surjection_relation(PS, PT), Type, _), Before, After) :-
handle_binary_exp(S, T, PS, PT, Before, After).
expressions(b(total_relation(S, T), Type, _), b(total_relation(PS, PT), Type, _), Before, After) :-
handle_binary_exp(S, T, PS, PT, Before, After).
expressions(b(total_surjection_relation(S, T), Type, _), b(total_surjection_relation(PS, PT), Type, _), Before, After) :-
handle_binary_exp(S, T, PS, PT, Before, After).
expressions(b(record_field(Expr, Id), Type, _), b(record_field(PExpr, PId), Type, _), Before, After) :-
expressions(Expr, PExpr, Before, After1),
expressions(Id, PId, After1, After).
expressions(b(rec(Fields), Type, _), b(rec(PFields), Type, _), Before, After) :-
process_all_expressions(Fields, PFields, Before, After).
expressions(field(Label, Carrier), field(Label, PCarrier), Before, After) :-
expressions(Carrier, PCarrier, Before, After).
expressions(b(struct(Exp), Type, _), b(struct(PExp), Type, _), Before, After) :-
process_all_expressions(Exp, PExp, Before, After).
expressions(b(seq(Exp), Type, _), b(seq(PExp), Type, _), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(b(insert_tail(Left, Rigth), Type, _), b(insert_tail(PLeft, PRigth), Type, _), Before, After) :-
handle_binary_exp(Left, Rigth, PLeft, PRigth, Before, After).
expressions(b(insert_front(Left, Rigth), Type, _), b(insert_front(PLeft, PRight), Type, _), Before, After) :-
handle_binary_exp(Left, Rigth, PLeft, PRight, Before, After).
expressions(b(general_sum(IdList, Pred, Result), Type, _), b(general_sum(PIdList, PPred, PResult), Type, _), Before, After) :-
handle_quantified_set_exp(IdList, Pred, Result, PIdList, PPred, PResult, Before, After).
expressions(b(general_product(IdList, Pred, Result), Type, _), b(general_product(PIdList, PPred, PResult), Type, _), Before, After) :-
handle_quantified_set_exp(IdList, Pred, Result, PIdList, PPred, PResult, Before, After).
expressions(b(general_union(Set), Type, _), b(general_union(PSet), Type, _), Before, After) :-
expressions(Set, PSet, Before, After).
expressions(b(general_intersection(Set), Type, _), b(general_intersection(PSet), Type, _), Before, After) :-
expressions(Set, PSet, Before, After).
expressions(b(comprehension_set(VarList, Predicate), Type, _), b(comprehension_set(PVarList, PPredicate), Type, _), Before, After) :-
process_all_expressions(VarList, PVarList, Before, After1),
predicates(Predicate, PPredicate, After1, After).
expressions(b(operation_call_in_expr(Id,Paras),_,_), b(operation_call_in_expr(PId,PParas),_,_), Before, After) :- !,
expressions(Id, PId, Before, After1),
process_all_expressions(Paras, PParas, After1, After).
expressions(set(Exp), set(PExp), Before, After) :-
expressions(Exp, PExp, Before, After).
expressions(seq(Exp), seq(PExp), Before, After) :-
expressions(set(couple(Exp, Exp)), set(couple(PExp, PExp)), Before, After).
expressions(couple(Left, Right), couple(PLeft, PRight), Before, After) :-
expressions(Left, PLeft, Before, After1),
expressions(Right, PRight, After1, After).
expressions(empty_set,empty_set, Before, Before).
expressions(X, _,_,_) :- !, add_st_error(X).