This section documents the predicates that are defined on dicts. We
use the naming and argument conventions of the traditional library(assoc)
.
- is_dict(@Term)
- True if Term is a dict. This is the same as
is_dict(Term,_)
.
- is_dict(@Term,
-Tag)
- True if Term is a dict of Tag.
- get_dict(?Key,
+Dict, -Value)
- Unify the value associated with Key in dict with Value.
If
Key is unbound, all associations in Dict are
returned on backtracking. The order in which the associations are
returned is undefined. This predicate is normally accessed using the
functional notation
Dict.Key
. See section
5.4.1.
Fails silently if Key does not appear in Dict. This is different from
the behavior of the functional‘.`-notation, which throws an
existence error in that case.
- [semidet]get_dict(+Key,
+Dict, -Value, -NewDict, +NewValue)
- Create a new dict after updating the value for Key. Fails if
Value does not unify with the current value associated with
Key. Dict is either a dict or a list the can be
converted into a dict.
Has the behavior as if defined in the following way:
get_dict(Key, Dict, Value, NewDict, NewValue) :-
get_dict(Key, Dict, Value),
put_dict(Key, Dict, NewValue, NewDict).
- dict_create(-Dict,
+Tag, +Data)
- Create a dict in Tag from Data. Data is
a list of attribute-value pairs using the syntax
Key:Value
,
Key=Value
, Key-Value
or Key(Value)
.
An exception is raised if Data is not a proper list, one of
the elements is not of the shape above, a key is neither an atom nor a
small integer or there is a duplicate key.
- dict_pairs(?Dict,
?Tag, ?Pairs)
- Bi-directional mapping between a dict and an ordered list of pairs (see section
A.33).
- put_dict(+New,
+DictIn, -DictOut)
- DictOut is a new dict created by replacing or adding
key-value pairs from New to Dict. New
is either a dict or a valid input for dict_create/3.
This predicate is normally accessed using the functional notation. Below
are some examples:
?- A = point{x:1, y:2}.put(_{x:3}).
A = point{x:3, y:2}.
?- A = point{x:1, y:2}.put([x=3]).
A = point{x:3, y:2}.
?- A = point{x:1, y:2}.put([x=3,z=0]).
A = point{x:3, y:2, z:0}.
- put_dict(+Key,
+DictIn, +Value, -DictOut)
- DictOut is a new dict created by replacing or adding
Key-Value to DictIn. For example:
?- A = point{x:1, y:2}.put(x, 3).
A = point{x:3, y:2}.
This predicate can also be accessed by using the functional notation,
in which case Key can also be a *path* of keys. For example:
?- Dict = _{}.put(a/b, c).
Dict = _6096{a:_6200{b:c}}.
- del_dict(+Key,
+DictIn, ?Value, -DictOut)
- True when Key-Value is in DictIn and DictOut
contains all associations of DictIn except for Key.
- [semidet]+Select :< +From
- True when Select is a‘sub dict' of From: the
tags must unify and all keys in Select must appear with
unifying values in From. From may contain keys
that are not in
Select. This operation is frequently used to match a
dict and at the same time extract relevant values from it. For example:
plot(Dict, On) :-
_{x:X, y:Y, z:Z} :< Dict, !,
plot_xyz(X, Y, Z, On).
plot(Dict, On) :-
_{x:X, y:Y} :< Dict, !,
plot_xy(X, Y, On).
The goal Select :< From
is equivalent to
select_dict(Select, From, _)
.
- [semidet]select_dict(+Select,
+From, -Rest)
- True when the tags of Select and From have been
unified, all keys in Select appear in From and the
corresponding values have been unified. The key-value pairs of From
that do not appear in Select are used to form an anonymous
dict, which us unified with Rest. For example:
?- select_dict(P{x:0, y:Y}, point{x:0, y:1, z:2}, R).
P = point,
Y = 1,
R = _G1705{z:2}.
See also :</2 to
ignore Rest and >:</2
for a symmetric partial unification of two dicts.
- +Dict1 >:< +Dict2
- This operator specifies a partial unification between
Dict1 and Dict2. It is true when the tags and the
values associated with all common keys have been unified. The
values associated to keys that do not appear in the other dict are
ignored. Partial unification is symmetric. For example, given a list of
dicts, find dicts that represent a point with X equal to zero:
member(Dict, List),
Dict >:< point{x:0, y:Y}.
See also :</2 and select_dict/3.
This section describes the destructive update operations defined on
dicts. These actions can only update keys and not add or remove
keys. If the requested key does not exist the predicate raises
existence_error(key, Key, Dict)
. Note the additional
argument.
Destructive assignment is a non-logical operation and should be used
with care because the system may copy or share identical Prolog terms at
any time. Some of this behaviour can be avoided by adding an additional
unbound value to the dict. This prevents unwanted sharing and ensures
that copy_term/2
actually copies the dict. This pitfall is demonstrated in the example
below:
?- A = a{a:1}, copy_term(A,B), b_set_dict(a, A, 2).
A = B, B = a{a:2}.
?- A = a{a:1,dummy:_}, copy_term(A,B), b_set_dict(a, A, 2).
A = a{a:2, dummy:_G3195},
B = a{a:1, dummy:_G3391}.
- [det]b_set_dict(+Key,
!Dict, +Value)
- Destructively update the value associated with Key in Dict
to
Value. The update is trailed and undone on backtracking. This
predicate raises an existence error if Key does not appear in
Dict. The update semantics are equivalent to setarg/3
and
b_setval/2.
- [det]nb_set_dict(+Key,
!Dict, +Value)
- Destructively update the value associated with Key in Dict
to a copy of Value. The update is not undone on
backtracking. This predicate raises an existence error if Key
does not appear in
Dict. The update semantics are equivalent to nb_setarg/3
and
nb_setval/2.
- [det]nb_link_dict(+Key,
!Dict, +Value)
- Destructively update the value associated with Key in Dict
to
Value. The update is not undone on backtracking.
This predicate raises an existence error if Key does not
appear in
Dict. The update semantics are equivalent to nb_linkarg/3
and
nb_linkval/2.
Use with extreme care and consult the documentation of
nb_linkval/2
before use.