Skip to content

Instantly share code, notes, and snippets.

@philtomson
Created December 2, 2011 22:55
Show Gist options
  • Save philtomson/1425225 to your computer and use it in GitHub Desktop.
Save philtomson/1425225 to your computer and use it in GitHub Desktop.
Using the Functorial interface to HashTbl
(* ( 'cs, 'conditions, 'actions, 'ns) *)
(* given a current state (cs)
* and condition - get the resulting actions and next state ('ns) *)
type 'a state = State of 'a ;;
type ('cs, 'cond, 'action, 'ns) st_entry = ST_Entry of ('cs * 'cond * 'action * 'ns);;
type state_list = st_entry list ;;
type ('cs, 'cond) st_cond = State_Cond of ('cs * 'cond) ;;
type ('action, 'ns) st_action_ns = Action_NS of ('action * 'ns);;
module States = struct
(* FILL_WSH and FILL_RNS allow for different temps for wash
* and rinse *)
type t = FILL_WSH | WASH | EMPTY | FILL_RNS | RINSE | SPIN | STOP
end ;;
(* probably need something like "signals" that can be put into expressions
* which can be evaluated
*)
module Conditions = struct
(*TODO: condition expressions*)
end;;
(* define a state list (declarative) *)
let my_fsm = [(States.FILL_WSH, "full", "water_on", States.WASH);
(States.WASH, "10Minutes", "agitate", States.EMPTY);
(States.EMPTY, "empty", "drain", States.FILL_RNS);
(States.FILL_RNS, "full", "water_on", States.RINSE);
(States.RINSE, "10Minutes", "agitate", States.EMPTY);
(States.EMPTY, "empty", "drain", States.SPIN);
(States.SPIN, "5Minutes", "motor_on", States.STOP);
(States.STOP, "*", "motor_off", States.STOP);
];;
module ST_Table = Hashtbl.Make(
struct
type t = States.t
let equal = (=)
let hash = Hashtbl.hash
end
);;
(*
module ST_Table :
sig
type key = States.t
type 'a t
val create : int -> 'a t
val clear : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val length : 'a t -> int
end
*)
let sh = ST_Table.create 5 ;; (* what if instead of '4' you could determine the number of options in States? *)
(* val sh : '_a ST_Table.t = <abstr> *)
(* now we build it from my_fsm list instead
ST_Table.add sh States.FILL ("full", States.WASH);;
ST_Table.add sh States.WASH ("after 10 minutes", States.EMPTY);;
ST_Table.add sh States.EMPTY ("empty", States.RINSE);;
ST_Table.add sh States.RINSE ("empty", States.SPIN);;
ST_Table.add sh States.SPIN ("after 5 minutes", States.STOP);;
*)
let _ = List.iter (fun (cs, cond, action, ns) -> ST_Table.add sh cs (cond, action, ns)) my_fsm;;
ST_Table.find_all sh States.FILL_WSH ;;
@built
Copy link

built commented Dec 7, 2011

Ah, thanks for explaining!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment