let rec v_mul v1 v2 = match v1 with
|Vec (size1, vec1) ->
(
match v2 with
|Vec (size2, vec2) ->
if size1 = size2 then
make_vector size1 (fun i -> v_mul (vec1 i) (vec2 i))
else raise (Value_operation "vector size not matched.")
|Zero -> make_vector size1 (fun i -> v_mul (vec1 i) Zero)
|_ -> raise (Value_operation "Vector_Scalar vec1 *~ sca2")
)
|N i1 ->
(
match v2 with
|N i2 -> normalize (return_N (i1 * i2))
|R f2 -> normalize (return_R ((float_of_int i1) *. f2))
|Vec (size2, vec2) ->
raise (Value_operation "Vector_Scalar i1 *~ vec2")
|Zero -> return_N 0
|W -> if i1 = 0 then N 0 else fail
)
|R f1 ->
(
match v2 with
|N i2 -> normalize (return_R (f1 *. (float_of_int i2)))
|R f2 -> normalize (return_R (f1 *. f2))
|Vec (size2, vec2) ->
raise (Value_operation "Vector_Scalar f1 *~ vec2")
|Zero -> return_R 0.
|W -> if f1 = 0. then R 0. else fail
)
|Zero ->
(
match v2 with
|N i2 -> return_N 0
|R f2 -> return_R 0.
|Vec (size2, vec2) -> make_vector size2 (fun i -> v_mul Zero (vec2 i))
|Zero -> Zero
|W -> Zero
)
|W ->
(
match v2 with
|N i2 -> if i2 = 0 then N 0 else fail
|R f2 -> if f2 = 0. then R 0. else fail
|Vec (size2, vec2) ->
raise (Value_operation "Vector_Scalar W +~ vec2")
|Zero -> Zero
|W -> fail
)