1234567891011121314151617181920212223242526272829(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)type('state,'context)rule={from:'state;label:string;guard:'context->int->bool;target:'state}type('state,'context)machine=('state,'context)rulelisttype'staterun={state:'state;since:int;fired:stringoption}letstart(s:'state):'staterun={state=s;since=0;fired=None}letstep(machine:('state,'context)machine)(context:'context)(run:'staterun):'staterun=(* [since + 1]: the steps spent in the state, this one included *)letsince=run.since+1inmatchList.find_opt(funr->r.from=run.state&&r.guardcontextsince)machinewith|Somer->{state=r.target;since=0;fired=Somer.label}|None->{runwithsince;fired=None}letafter(n:int)(_:'context)(since:int):bool=since>=nletstates(machine:('state,'context)machine):'statelist=List.fold_left(funaccr->List.fold_left(funaccs->ifList.memsaccthenaccelseacc@[s])acc[r.from;r.target])[]machine