Standard pairs are generated
?- dict_pairs(_{a:1,b:2},T,P). P = [a-1,b-2].
Note that
Going in "disassembly" direction, this predicate behaves like findall/3 in that it relates an empty Dict to an empty Pairs
?- dict_pairs(_{},Tag,Pairs). Pairs = [].
rather than like bagof/3, which would fail in case of an empty Dict:
?- Dict=_{}, bagof(Key-Value,get_dict(Key,Dict,Value),Bag). false.
This makes sense when you in the direction of "assembly":
?- dict_pairs(Dict,tag,[]). Dict = tag{}.
Need doc fix
"ordered list of pairs" means (probably) "ordered by natural order of keys"
It should be:
"Bi-directional mapping between Dict and the pair (Tag, Pairs), where Pairs is an ordered list of pairs if Pairs is ouput"
The predicate doesn't care about ordering when Pairs is input. Duplicate keys, however, lead to an exception.
When verifying Pairs against Dict, the order matters. Duplicates in Pairs lead to failure.
Some unit testing code
dict_assembly_disassembly_testing.pl
An application
Suppose you have an RDBMS-like description of field names and field data:
data_fields(1,2,3). data(a1,b1,b2). data(a2,b2,c2).
You can transform the above into dict form:
build_dict_from_tabular_terms(Tag,NameTerm,ValueTerm,Dict) :- compound_name_arguments(NameTerm,_,Names), compound_name_arguments(ValueTerm,_,Values), build_dict_from_lists(Tag,Names,Values,Dict). build_dict_from_lists(Tag,Names,Values,Dict) :- zip_unzip(Names,Values,Pairs), dict_pairs(Dict,Tag,Pairs). zip_unzip(Names,Values,Zipped) :- maplist([N,V,N-V]>>true,Names,Values,Zipped).
Then:
?- build_dict_from_tabular_terms(foo,data_fields(1,2,3),data(a,b,c),Dict). Dict = foo{1:a,2:b,3:c}.
However, this works only one-way, separate code is needed for the Dict-to-Term direction.