% This LaTeX document was generated using the LaTeX backend of PlDoc,
% The SWI-Prolog documentation system



\section{library(dicts): Dict utilities}

\label{sec:dicts}

This library defines utilities that operate on lists of dicts, notably
to make lists of dicts consistent by adding missing keys, converting
between lists of compounds and lists of dicts, joining and slicing lists
of dicts.\vspace{0.7cm}

\begin{description}
    \predicate[semidet]{dicts_same_tag}{2}{+List, -Tag}
True when \arg{List} is a list of dicts that all have the tag \arg{Tag}.

    \predicate[det]{dict_keys}{2}{+Dict, -Keys}
True when \arg{Keys} is an ordered set of the keys appearing in \arg{Dict}.

    \predicate[semidet]{dicts_same_keys}{2}{+List, -Keys}
True if \arg{List} is a list of dicts that all have the same keys and
\arg{Keys} is an ordered set of these keys.

    \predicate{dicts_to_same_keys}{3}{+DictsIn, :OnEmpty, -DictsOut}
\arg{DictsOut} is a copy of \arg{DictsIn}, where each dict contains all keys
appearing in all dicts of \arg{DictsIn}. Values for keys that are
added to a dict are produced by calling \arg{OnEmpty} as below. The
predicate \predref{dict_fill}{4} provides an implementation that fills all
new cells with a predefined value.

\begin{code}
call(:OnEmpty, +Key, +Dict, -Value)
\end{code}

    \predicate[det]{dict_fill}{4}{+ValueIn, +Key, +Dict, -Value}
Implementation for the \predref{dicts_to_same_keys}{3} \arg{OnEmpty} closure
that fills new cells with a copy of \arg{ValueIn}. Note that
\predref{copy_term}{2} does not really copy ground terms. Below are two
examples. Note that when filling empty cells with a variable,
each empty cell is bound to a new variable.

\begin{code}
?- dicts_to_same_keys([r{x:1}, r{y:2}], dict_fill(null), L).
L = [r{x:1, y:null}, r{x:null, y:2}].
?- dicts_to_same_keys([r{x:1}, r{y:2}], dict_fill(_), L).
L = [r{x:1, y:_G2005}, r{x:_G2036, y:2}].
\end{code}

Use \predref{dict_no_fill}{3} to raise an error if a dict is missing a key.

    \predicate[semidet]{dicts_join}{3}{+Key, +DictsIn, -Dicts}
Join dicts in \arg{Dicts} that have the same value for \arg{Key}, provided
they do not have conflicting values on other keys. For example:

\begin{code}
?- dicts_join(x, [r{x:1, y:2}, r{x:1, z:3}, r{x:2,y:4}], L).
L = [r{x:1, y:2, z:3}, r{x:2, y:4}].
\end{code}

\begin{tags}
    \tag{Errors}
\verb$existence_error(key, Key, Dict)$ if a dict in Dicts1
or Dicts2 does not contain \arg{Key}.
\end{tags}

    \predicate[semidet]{dicts_join}{4}{+Key, +Dicts1, +Dicts2, -Dicts}
Join two lists of dicts (\arg{Dicts1} and \arg{Dicts2}) on \arg{Key}. Each pair
D1-D2 from \arg{Dicts1} and \arg{Dicts2} that have the same (\Sequal{}) value for
\arg{Key} creates a new dict D with the union of the keys from D1 and
D2, provided D1 and D2 to not have conflicting values for some
key. For example:

\begin{code}
?- DL1 = [r{x:1,y:1},r{x:2,y:4}],
   DL2 = [r{x:1,z:2},r{x:3,z:4}],
   dicts_join(x, DL1, DL2, DL).
   DL = [r{x:1, y:1, z:2}, r{x:2, y:4}, r{x:3, z:4}].
\end{code}

\begin{tags}
    \tag{Errors}
\verb$existence_error(key, Key, Dict)$ if a dict in \arg{Dicts1}
or \arg{Dicts2} does not contain \arg{Key}.
\end{tags}

    \predicate[det]{dicts_slice}{3}{+Keys, +DictsIn, -DictsOut}
\arg{DictsOut} is a list of Dicts only containing values for \arg{Keys}.

    \predicate[semidet]{dicts_to_compounds}{4}{?Dicts, +Keys, :OnEmpty, ?Compounds}
True when \arg{Dicts} and \arg{Compounds} are lists of the same length and
each element of \arg{Compounds} is a compound term whose arguments
represent the values associated with the corresponding keys in
\arg{Keys}. When converting from dict to row, \arg{OnEmpty} is used to
compute missing values. The functor for the compound is the same
as the tag of the pair. When converting from dict to row and the
dict has no tag, the functor \const{row} is used. For example:

\begin{code}
?- Dicts = [_{x:1}, _{x:2, y:3}],
   dicts_to_compounds(Dicts, [x], dict_fill(null), Compounds).
Compounds = [row(1), row(2)].
?- Dicts = [_{x:1}, _{x:2, y:3}],
   dicts_to_compounds(Dicts, [x,y], dict_fill(null), Compounds).
Compounds = [row(1, null), row(2, 3)].
?- Compounds = [point(1,1), point(2,4)],
   dicts_to_compounds(Dicts, [x,y], dict_fill(null), Compounds).
Dicts = [point{x:1, y:1}, point{x:2, y:4}].
\end{code}

When converting from \arg{Dicts} to \arg{Compounds} \arg{Keys} may be computed by
\predref{dicts_same_keys}{2}.
\end{description}

