module 'data.atom' { /** check(X). * Succeeds if X is instantiated to an atom. */ check(Atom) :- 'kernel':atom_check(Atom). /** length(Atom, Length). * * Atom is an instantiated atom. * * Succeeds if the length of Atom is Length. */ length(Atom, Length) :- 'kernel':atom_length(Atom, Length). /** concat(A, B, R). * * At least two of A, B and * R are instantiated atoms. * * Succeeds if R is the concatenation of A * and B. */ concat(A, B, R) :- 'kernel':atom_concat(A, B, R). /** new(Atom). * * Atom is uninstantiated. * * Atom is unified with a fresh atom. */ new(Atom) :- 'kernel':atom_new(Atom). /** new_backtrackable(Atom). * * Atom is uninstantiated. * * Atom is unified with a fresh atom. Generated atoms are * reused on backtrack. */ new_backtrackable(Atom) :- 'kernel':atom_new_backtrackable(Atom). /** string(Atom, String). * * Atom is instantiated to an atom. * * Succeeds if String is the string containing to * the name of Atom. */ string(Atom, String) :- 'kernel':atom_to_string(Atom, String). /** sub(Atom, Before, Length, After, SubAtom). * * Atom is an instantiated atom. * * * Either SubAtom is an instantiated atom or at least * two of Before, Length and * After are instantiated integers. * * Succeeds if Atom is the concatenation of * atoms Left, SubAtom and * Right, with respective lengths * Before, Length and * After. */ sub(Atom, Before, Length, After, SubAtom) :- 'kernel':atom_sub(Atom, Before, Length, After, SubAtom). /** format(Format, Args, Atom). * * Format is a format specification and * Args is a suitable list of arguments. * * Succeeds if Atom contains the formatted * text. */ format(Format, Args, Atom) :- 'kernel':atom_format(Format, Args, Atom). /** join(Atoms, Delim, Atom). * * Atoms is a list of instantiated atoms. * Delim is an instantiated atom. * * Succeeds if Atom is the concatenation * of atoms enumerated in Atoms, separated * with Delim. */ join(Atoms, Delim, Atom) :- 'data.atom':string(Delim, DelimStr), module Convert { do(Atom, String) :- 'data.atom':string(Atom, String). }, 'data.list':join('data.list':iter(Atoms, Convert), DelimStr, String), 'data.string':atom(String, Atom). /** split(Atom, Delim, Atoms). * * Atoms is a list of instantiated atoms. * * * Delim is an instantiated character. * * Succeeds if Atoms is the list of * sub-atoms of Atom delimited * with Delim. */ split(Atom, Delim, Atoms) :- split_from(0, 0, Atom, Delim, Atoms). split_from(Origin, Index, Atom, Delim, Atoms) :- length(Atom, Length), ( 'data.number':(Index < Length) -> 'data.number':succ(Index, SuccIndex), ( sub(Atom, Index, 1, _, Delim) -> sub(Atom, Origin, 'data.number':(Index - Origin), _, C), Atoms = [C | Tail], split_from(SuccIndex, SuccIndex, Atom, Delim, Tail) ; split_from(Origin, SuccIndex, Atom, Delim, Atoms) ) ; sub(Atom, Origin, _, 0, C), Atoms = [C] ). /** split_at_delim_left(Atom, Delim, Left, Right). * * Atom is an instantiated atom. * * * Delim is an instantiated character. * * Succeeds if Atom contains at least * one occurrence of Delim, and * Left is the prefix before the left-most * occurrence, and Right the suffix * starting immediately after it. */ split_at_delim_left(Atom, Delim, Left, Right) :- split_at_delim_left_from(0, Atom, Delim, Left, Right). split_at_delim_left_from(Index, Atom, Delim, Left, Right) :- length(Atom, Length), ( 'data.number':(Index < Length) -> 'data.number':succ(Index, SuccIndex), ( sub(Atom, Index, 1, _, Delim) -> sub(Atom, 0, Index, _, Left), sub(Atom, SuccIndex, _, 0, Right) ; split_at_delim_left_from( SuccIndex, Atom, Delim, Left, Right ) ) ; fail ). /** split_at_delim_right(Atom, Delim, Left, Right). * * Atom is an instantiated atom. * * * Delim is an instantiated character. * * Succeeds if Atom contains at least * one occurrence of Delim, and * Left is the prefix before the right-most * occurrence, and Right the suffix * starting immediately after it. */ split_at_delim_right(Atom, Delim, Left, Right) :- length(Atom, Length), split_at_delim_right_from( 'data.number':pred(Length), Atom, Delim, Left, Right ). split_at_delim_right_from(Index, Atom, Delim, Left, Right) :- ( 'data.number':(Index >= 0) -> ( sub(Atom, Index, 1, _, Delim) -> sub(Atom, 0, Index, _, Left), sub(Atom, 'data.number':succ(Index), _, 0, Right) ; split_at_delim_right_from( 'data.number':pred(Index), Atom, Delim, Left, Right ) ) ; fail ). /** subst(Src, Table, Tgt). Src is an atom. Table is a list with elements of the form A => B where A and B are atoms. Succeeds if Tgt is the atom obtained from Src by substituting every occurrences of sub-atom A in Src by B, for every A => B in Table. */ subst(Src, Table, Tgt) :- Tgt = 'data.string':atom( 'data.list':subst( 'data.atom':string(Src), 'data.list':iter(Table) { do(From => To) = ('data.atom':string(From) => 'data.atom':string(To)). } ) ). number(Atom) = 'kernel':atom_to_number(Atom). }