-module(automata).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/automata.gleam").
-export([new/3, initial_state/1, step/3, run/2, accepts/2]).
-export_type([automaton/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-opaque automaton(DKT, DKU) :: {automaton,
DKT,
fun((DKT, DKU) -> DKT),
fun((DKT) -> boolean())}.
-file("src/automata.gleam", 16).
?DOC(
" Construct an automaton from its initial state, transition\n"
" function, and acceptance predicate.\n"
).
-spec new(DKV, fun((DKV, DKW) -> DKV), fun((DKV) -> boolean())) -> automaton(DKV, DKW).
new(Initial_state, Transition, Accepting) ->
{automaton, Initial_state, Transition, Accepting}.
-file("src/automata.gleam", 29).
?DOC(" Return the initial state.\n").
-spec initial_state(automaton(DKZ, any())) -> DKZ.
initial_state(Automaton) ->
erlang:element(2, Automaton).
-file("src/automata.gleam", 35).
?DOC(
" Apply one transition from the supplied state using one input\n"
" symbol.\n"
).
-spec step(automaton(DLD, DLE), DLD, DLE) -> DLD.
step(Automaton, State, Symbol) ->
(erlang:element(3, Automaton))(State, Symbol).
-file("src/automata.gleam", 45).
?DOC(
" Fold a list of input symbols over the automaton's transition\n"
" function and return the resulting state.\n"
).
-spec run(automaton(DLH, DLI), list(DLI)) -> DLH.
run(Automaton, Inputs) ->
gleam@list:fold(
Inputs,
erlang:element(2, Automaton),
fun(State, Symbol) -> (erlang:element(3, Automaton))(State, Symbol) end
).
-file("src/automata.gleam", 52).
?DOC(" Return True when the automaton accepts the supplied input.\n").
-spec accepts(automaton(any(), DLN), list(DLN)) -> boolean().
accepts(Automaton, Inputs) ->
(erlang:element(4, Automaton))(run(Automaton, Inputs)).