\documentclass[a4paper]{article}
\usepackage{fullpage}
\usepackage{listings}
\usepackage{xcolor}

\title{A formalization of a simulation engine for hybrid systems}
\author{}
\date{}

\setlength{\parindent}{0pt}

\lstdefinelanguage{ml}{
  basicstyle=\ttfamily,
  morekeywords=[1]{
    type, float, option, let, fun, with, if, else, then, in, as, match,
  },
  morekeywords=[2]{
    HNode, DNode, Idle, Running, Discrete, Continuous
  },
  keywordstyle=[1]{\color{blue}},
  keywordstyle=[2]{\color{red}},
  commentstyle=\itshape,
  columns=[l]fullflexible,
  sensitive=true,
  morecomment=[s]{(*}{*)},
  keepspaces=true,
  literate=
    {'a}{$\alpha$}{1}
    {'b}{$\beta$}{1}
    {'p}{$\rho$}{1}
    {'s}{$\sigma$}{1}
    {'y}{$y$}{1}
    {'yder}{$\dot{y}$}{1}
    {'zin}{$z_{in}$}{1}
    {'zout}{$z_{out}$}{1}
    {fun\ }{$\lambda$}{1}
    {->}{$\to$}{1}
    {+.}{$+$}{1}
    {-.}{$-$}{1}
    {=}{$=$}{1}
    {>=}{$\geq$}{1}
    {<=}{$\leq$}{1}
}
\lstnewenvironment{ml}{\lstset{language=ml}}{}
\newcommand{\mlf}[1]{\lstinline[language=ml]{#1}}


\begin{document}
\maketitle

A discrete synchronous function, or node, can be seen as a pair of a step and 
reset function, which operate on an inner state:

\begin{ml}
  type ('p, 'a, 'b) dnode =
    DNode : { s : 's;
              step  : 's -> 'a -> 'b * 's;
              reset : 'p -> 's -> 's } -> ('p, 'a, 'b) dnode
\end{ml}

A hybrid node is quite similar: it has an inner state, a step and a reset 
function; but the step function is decomposed into multiple distinct elements
for the purpose of the simulation:

\begin{ml}
  type ('p, 'a, 'b, 'y, 'yder, 'zin, 'zout) hnode =
    HNode : { s : 's;
              step : 's -> 'a -> 'b * 's;
              fder : 's -> 'a -> 'y -> 'yder;
              fzer : 's -> 'a -> 'y -> 'zout;
              fout : 's -> 'a -> 'y -> 'b;
              reset : 'p -> 's -> 's;
              horizon : 's -> time;
              jump : 's -> bool;
              cget : 's -> 'y;
              cset : 's -> 'y -> 's;
              zset : 's -> 'zin -> 's;
            } -> ('p, 'a, 'b, 'y, 'yder, 'zin, 'zout) hnode
\end{ml}

\mlf{step} and \mlf{reset} are on discrete steps, and behave in the same way as 
for a discrete node. \mlf{fder}, \mlf{fzer} and \mlf{fout} are used during
integration phases with a solver. \mlf{fder} represents the derivative function
in an initial value problem. \mlf{fzer} is the zero-crossing function, which
computes the values of all zero-crossing function we wish to monitor. \mlf{fout}
computes the output of the system at a particular instant.

\begin{figure}
   \begin{ml}
let sim (HNode model) (DNode solver) =
  let s = { status = Idle; mstate = model.state; sstate = solver.state } in 
  let step state input =
    match input, state.status with
    | Some i, _ ->
        let status = Running
          { mode = Continuous; input = i; now = 0.0; stop = i.length } in
        None, { state with status }
    | None, Idle -> None, state
    | None, Running ({ mode = Discrete; _ } as r) ->
        let o, mstate = model.step state.mstate (r.input.u r.now) in
        let state =
          let h = model.horizon mstate in
          if h <= 0.0 then { state with mstate }
          else if r.now >= r.stop then s
          else if model.jump mstate then
            let y      = model.cget mstate in
            let fder t = model.fder mstate (offset r.input r.now t) in
            let fzer t = model.fzer mstate (offset r.input r.now t) in
            let ivp    = { fder; stop = r.stop -. r.now; init = y } in
            let zc     = { yc = y; fzer } in
            let sstate = solver.reset (ivp, zc) state.sstate in
            let status = Running { r with mode = Continuous } in
            { status; mstate; sstate }
          else { state with status = Running { r with mode = Continuous } }
        in Some { start = r.now; length = 0.0; u = fun _ -> o }, state
    | None, Running ({ mode = Continuous; _ } as r) ->
        let (h, f, z), sstate = solver.step state.sstate r.stop in
        let mstate = model.cset state.mstate (f h) in
        let now = r.input.start +. h in
        let state = match z with
        | None ->
            let status =
              if h >= r.stop then Running { r with mode = Discrete; now }
              else Running { r with now } in
            { status; mstate; sstate }
        | Some z ->
            let status = Running { r with mode = Discrete; now } in
            { status; mstate = model.zset mstate z; sstate } in
        let fout t =
          model.fout mstate (r.input.u (r.now +. t)) (f (r.now +. t)) in
        let out =
          { start = r.input.start +. r.now; length = h -. r.now; u = fout } in
        Some out, state in
  let reset (m, s) { mstate; sstate; _ } =
    let mstate = model.reset m mstate in
    let sstate = solver.reset s sstate in
    { status = Idle; mstate; sstate } in
  DNode { state = s; step; reset }
   \end{ml}
   \label{fig:ml:sim}
   \caption{Hybrid System Simulation}
\end{figure}


\end{document}
