```(* Coulomb friction *)
let hybrid sgn(x) =
present up(x) -> 1.0 | up(-. x) -> -1.0 init 0.0

let hybrid coulomb(gain, offset, x) = y where
rec y = sgn(x) *. (gain *. abs_float (x) +. offset)

let hybrid coulomb_scalar_input(n)(gain, offset, x) = y where
rec
g = gain *. abs_float (x)
and
forall i in 0 .. (n - 1), offseti in offset, yi out y do
yi = sgn(x) *. (g +. offseti)
done

let hybrid coulomb_vectors(n)(gain, offset, x) = y where
rec
forall i in 0 .. (n - 1), xi in x, offseti in offset, yi out y do
yi = sgn(xi) *. (gain *. abs_float (xi) +. offseti)
done

(* Quantizer *)
let hybrid quantizer(q, u) = n where
rec init n = q *. floor(u /. q)
and nq = n *. q
and present up(u -. nq -. q) -> do n = last n +. 1.0 done
| up(nq -. u) -> do n = last n -. 1.0 done

(* Saturation block *)
let saturation(upper, lower, u) = min (max lower u) upper

(* Relay *)
let hybrid relay(son, so , von, vo , u) = r where
rec automaton
| On -> do r = von unless up(so -. u) then Off
| Off -> do r = vo  unless up(u -. son) then On
end

(* Comparison, rising, falling edges *)
type pos = Positive | Negative | Between

let hybrid compare(epsilon, x) = pos where
rec automaton
| BeetweenState ->
do pos = Between
unless up(x -. epsilon) then PositiveState
else up(-. x) then NegativeState
| PositiveState ->
do pos = Positive unless up(-. x) then NegativeState
| NegativeState ->
do pos = Negative unless up(x -. epsilon) then PositiveState
end

let hybrid dead_zone(ll, ul, u) = y where
rec epsilon = 0.0
and y = match compare(epsilon, u -. ul +. epsilon) with
| Positive -> u -. ul
| Between | Negative ->
match compare(epsilon, u -. ll -. epsilon) with
| Negative -> u -. ll
| Positive | Between -> 0.0

(* Backlash *)
(*
let hybrid backlash (width, y0, (u, u')) = y where
rec half_width = width /. 2.0
and init y = y0
and automaton
| Disengaged ->
do unless up(u -. (y +. half_width)) then Engaged_positive
else up( -.u +. (y -. half_width)) then Engaged_negative
| Engaged_positive ->
do y = u -. half_width unless up(-. u') then Disengaged
| Engaged_negative ->
do y = u +. half_width unless up(u') then Disengaged
end
*)

let hybrid backlash (width, y0, (u, u')) = y where
rec half_width = width /. 2.0
and init y = y0
and automaton
| Disengaged ->
do unless up(u -. (last y +. half_width)) then Engaged_positive
else up( -.u +. (last y -. half_width)) then Engaged_negative
| Engaged_positive ->
do y = u -. half_width unless up(-. u') then Disengaged
| Engaged_negative ->
do y = u +. half_width unless up(u') then Disengaged
end

```