# Getting all key-value pairs out of a dict using bagof/3 fails, but succeeds with findall/3

**URL:** <https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642>\
**Category:** Help!\
**Created:** [July 16, 2020, 2:57pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642 "2020-07-16T14:57:09Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [July 16, 2020, 2:57pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/1 "2020-07-16T14:57:09Z")

</div>

Probably something borderline:

I have here some test code where retrieval of all key-value pairs from a Dict works with findall/3, but fails with bagof/3. I have tried a few ways to do it, commented out here, but the one currently commented in should work as I see it. Instead, bagof/3 just fills the bag with a single solution:

```prolog
:- begin_tests(dicts).

   empty_dict(foo{}).
   nonempty_dict(foo{x:alpha, y:bravo, z:charlie}).
   
   bagof_call(Value,Dict,Key) :- (Value = Dict.Key).

   % Using bagof/3 to get all key-value pairs out of a dict
   
   test(test01_get_all_content_using_bagof, [true(T)]) :-
      nonempty_dict(Dict),
      % bagof(Key-Value, Value = Dict.get(Key), Bag), % NO
      % bagof(Key-Value, get_dict_ex(Key,Dict,Value), Bag), % NOT FOUND
      % bagof(Key-Value, bagof_call(Value,Dict,Key), Bag), % YES
      % bagof(Key-Value, get_dict(Key,Dict,Value), Bag), % YES      
      bagof(Key-Value, (Value = Dict.Key), Bag), % NO
      keysort(Bag,SortedBag),
      T = (SortedBag == [x-alpha, y-bravo, z-charlie]).

   % Using findall/3 to get all key-value pairs out of a dict
   
   test(test02_get_all_content_using_findall, [true(T)]) :-
      nonempty_dict(Dict),      
      % findall(Key-Value, Value = Dict.get(Key), Bag), % YES
      % findall(Key-Value, get_dict_ex(Key,Dict,Value), Bag), % NOT FOUND      
      % findall(Key-Value, get_dict(Key,Dict,Value), Bag), % YES
      findall(Key-Value, (Value = Dict.Key), Bag), % YES
      keysort(Bag,SortedBag),
      T = (SortedBag == [x-alpha, y-bravo, z-charlie]).
     
:- end_tests(dicts).

rt(dicts) :- run_tests(dicts).

```

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [July 16, 2020, 4:43pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/2 "2020-07-16T16:43:29Z")

</div>

~~I think this is because the `Value = Dict.Key` expands into something with intermediate variables that aren’t qualified in the `bagof`, but `findall` will qualify event those intermediate variables.~~

Oh actually, it looks like a dict inside a findall just gets expanded incorrectly:

```prolog
test_get_bag(Dict, Bag) :-
    bagof(Key-Value, (Value = Dict.Key), Bag).

?- listing(test_get_bag).
test_get_bag(A, E) :-
    '.'(A, B, D),
    bagof(B-C, C=D, E).

test_get_findall(Dict, Bag) :-
    findall(Key-Value, (Value = Dict.Key), Bag).

?- listing(test_get_findall).
test_get_findall(Dict, Bag) :-
    findall(Key-Value,
            ( '.'(Dict, Key, A),
              Value=A
            ),
            Bag).

```

I guess if bagof did get expanded correctly, then my above comment would be the cause (i.e. the `A` variable we see in the `findall` needs to be existentially qualified to work with bagof).

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 17, 2020, 8:20am UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/4 "2020-07-17T08:20:16Z")

</div>

Pushed a fix (4ee28abda5e826a3d98791cd588d7ff7ac885e3a) for this. Also automatically adds the intermediate variables to the existential variable set.

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [July 17, 2020, 8:59am UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/5 "2020-07-17T08:59:18Z")

</div>

Wow, that’s some quick turnaround 👌

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 17, 2020, 12:58pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/7 "2020-07-17T12:58:09Z")

</div>

> [@anon95304481](#):
>
> Might or might not work if a [bagof/3](https://www.swi-prolog.org/pldoc/doc_for?object=bagof/3) contains another [bagof/3](https://www.swi-prolog.org/pldoc/doc_for?object=bagof/3) and dicts are also involved.

It is likely that there are more corner cases. Given an untyped language with code-is-data this stuff is hard to get correct for all corner cases.

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [July 17, 2020, 3:07pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/8 "2020-07-17T15:07:30Z")

</div>

The developer will have to make things clear to himself/herself by adding helper predicates in any case before drifting off into complexity like Aguirre on a float.

Programming … it’s all about staying in P. But it’s mainly about human cognitive limits.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 17, 2020, 3:09pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/9 "2020-07-17T15:09:05Z")

</div>

> [@dtonhofer](#):
>
> staying in P.

Please explain. 😕

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [July 17, 2020, 7:52pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/10 "2020-07-17T19:52:57Z")

</div>

I assume dtonhofer means “staying in the [complexity class of P](https://en.wikipedia.org/wiki/P_(complexity)) (vs NP)”

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [July 20, 2020, 1:11pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/11 "2020-07-20T13:11:56Z")

</div>

It is just a pithy way to say that all of Computer Science would collapse and we would all be out of a job if we were able to not care about optimizations. Actually, the guys from the electronics lab would be able to do it all by themselves.

Finagling with sorting algorithms for example is all about keeping space and time (and energy) requirements at (low) powers of a polynomial in the size of the problem.

And of course, writing complex problems hits another limit relatively rapidly: humans can’t write programs very well. 7 chunks held in short-term memory is lousy. If your compiler has bugs that will only become apparent in highly complex, imbricated code, you may well be safe! Unless you let a student loose, because he/she is still unaware of cognitive limits and still free of the reflexes that makes one avoid those particular minefields.

You may be aware of this related fun read by Scott Aaronson: [https://www.scottaaronson.com/papers/npcomplete.pdf](https://www.scottaaronson.com/papers/npcomplete.pdf)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [July 20, 2020, 1:14pm UTC](https://swi-prolog.discourse.group/t/getting-all-key-value-pairs-out-of-a-dict-using-bagof-3-fails-but-succeeds-with-findall-3/2642/12 "2020-07-20T13:14:52Z")

</div>

> [@dtonhofer](#):
>
> You may be aware of this related fun read by Scott Aaronson: [https://www.scottaaronson.com/papers/npcomplete.pdf](https://www.scottaaronson.com/papers/npcomplete.pdf)

Nice, it notes [holographic bound](https://en.wikipedia.org/wiki/Bousso%27s_holographic_bound).
