# Compile Time Transforms in IC

1. Factor out all blatantly non-linear sub-expressions, replacing them with a place-holder temporary variable.

- Non-linear sub-expressions are divisions `'/'/2`, embedded reified constraint terms eg.`*=/2` and all functions except `eval/1`.
- Products `*/2` are not factored out.
- Recursively transform all factored sub-expressions.

2. If the remaining expression is linear, then transform it into a specialised propagator.
   - `X =:= Y` becomes nothing, but the valiables are unifed `X = Y` at compile time
3. If the remaining expression is not linear, then delay processing until run-time.

## Examples

### Compile time linear

`X =:= 3 * A + 4 * B` becomes `ic_lin_eq/3`
`X =:= 1 + 3 * A` becomes `ic_2v_eq/6`
`X =:= 3 * A` becomes `ic_1v_eq/4`

### Compile time maybe linear

`X =:= A + eval(E)` becomes `X =:= A + E` and is re-processed at run-time. Note the removal of the `eval/1` wrapper.
`X =:= A + B*C` becomes `X =:= A + B*C` (ie is left allone sice it contains variable products)

### Compile time linear after factoring

`X =:= 1 + A + 2*B + sin(C + 3*D)` becomes `ic_lin_eq(T2 =:= C + 3*D)`, `T1 iis sin(T2)`, `ic_lin_eq(X =:= 1 + A + 2*B + T1)`

### Compile time maybe linear after factoring

`X =:= 1 + A*sin(C + 3*D)` becomes `ic_lin_eq(T2 =:= C + 3*D)`, `T1 iis sin(T2)`, `X =:= 1 + A*T1`. Note that what is left of the original constraint will be re-processed at run-time.

### Compile time clearly non-linear

`X =:= sin(Y)` becomes `X iis sin(Y)`. Note there will be a temporary form where `X =:= T1` and `T1 iis sin(Y)`, but `X =:= T1` will be collapsed to nothing and the variables `X` and `T1` will be unified at compile time, resulting in `X iis sin(Y)`