The atom/number/string conversion family: atom_codes/2 atom_chars/2 atom_length/2 atom_concat/3 char_code/2 number_codes/2 number_chars/2 upcase_atom/2 downcase_atom/2 atomic_list_concat/2,3
(classic ISO/de-facto predicates, working over atoms) plus
atom_string/2 string_to_atom/2 string_concat/3 string_chars/2 string_codes/2 string_length/2 number_string/2 split_string/4
(SWI-style predicates producing/consuming real strings), all built
on the shared
atomic_text/1/require_atomic_text/2 "coerce an atomic term (atom,
number, or real string) to its text" primitive. string/1's own type
check lives in Episteme.Engine directly, alongside every other type
check (atom/1, var/1, ...), not here.
atom_codes/2/number_codes/2/string_codes/2 produce plain Elixir
charlists (String.to_charlist/1), which already are Episteme code
lists -- no wrapping needed, same as everywhere else a Prolog list is
just a native Elixir list. atom_chars/2/number_chars/2 instead
produce single-character atoms (classic ISO char_list semantics),
while string_chars/2 produces single-character strings -- the two
are not interchangeable.
Summary
Functions
Atomic's text, if it's an atom, a number, or a real string --
:error for anything else (a compound, a list, or an unbound
variable -- callers needing an instantiation_error specifically
should check for %Var{} themselves before calling this, same as
require_atomic_text/2 does).
Resolves term and returns its text, raising instantiation_error/type_error(atomic, _) as appropriate -- the shared entry point every predicate here uses to read a bound atomic argument.
Like require_atomic_text/2, but fails (instead of raising type_error) for an unbound variable -- callers that already have their own instantiation-error handling, or that want a plain proper-list-of-elements shape check first.
Unifies every {term, value} pair against bindings in order, failing outright the moment one doesn't -- the shared "generate one candidate, let unify filter it" tail every enumerating predicate here (atom_concat/3, string_concat/3, sub_atom/5) ends in.
Functions
Atomic's text, if it's an atom, a number, or a real string --
:error for anything else (a compound, a list, or an unbound
variable -- callers needing an instantiation_error specifically
should check for %Var{} themselves before calling this, same as
require_atomic_text/2 does).
@spec dispatch(atom(), non_neg_integer(), [term()]) :: Ichor.Backtrack.goal() | :not_handled
@spec require_atomic_text(term(), Ichor.Backtrack.Bindings.t()) :: String.t()
Resolves term and returns its text, raising instantiation_error/type_error(atomic, _) as appropriate -- the shared entry point every predicate here uses to read a bound atomic argument.
@spec unify_goal(term(), term(), Ichor.Backtrack.Bindings.t()) :: Ichor.Backtrack.Tree.t()
Like require_atomic_text/2, but fails (instead of raising type_error) for an unbound variable -- callers that already have their own instantiation-error handling, or that want a plain proper-list-of-elements shape check first.
@spec unify_pairs([{term(), term()}], Ichor.Backtrack.Bindings.t()) :: Ichor.Backtrack.Tree.t()
Unifies every {term, value} pair against bindings in order, failing outright the moment one doesn't -- the shared "generate one candidate, let unify filter it" tail every enumerating predicate here (atom_concat/3, string_concat/3, sub_atom/5) ends in.