optimizer: move more things inside let and begin

Refactor the code to move inside 'let' or 'begin'.

Also, in the test position of a 'if', recognize the 'not' inside a 'let' or 'begin'.
For example, transform (if (begin ... (not p)) x y) => (if (begin ... p) y x)
Previously, this conversion was made only when
the 'not' was the outermost expression.

And use the refactored code to move application inside 'let' or 'begin' in a single step
For example, transform ((let (...) ... (let (...) ... f) x) => (let (...) ... (let (...) ... (f x))
In the conversion, it's necessary to shift x to the new coordinates inside the 'let's.
In the new version x is shifted only once.

The changes to check_app_let_rator are not straightforward. I changed ((head->count==1) && (head->num_clauses ==1)) to ((clv->count == 1) && (clv->position == 0). I'm not sure that the current tests check that the flags are adjusted correctly.