\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}