# Dict access odd behavior

**URL:** <https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860>\
**Category:** Help!\
**Created:** [February 13, 2020, 1:58pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860 "2020-02-13T13:58:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [February 13, 2020, 1:58pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/1 "2020-02-13T13:58:07Z")

</div>

Hi,

Trying to understand why the different behavior in dict access in the following calls:

```nohighlight
?- current_input(S), read_term(S, T, []), T = (_ :- G), writeq(G), nl, call(G).
|: p :- A.foo = [].
_11462.foo=[]
false.

?- A.foo = [].
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [13] throw(error(instantiation_error,_11490))
ERROR: [10] '<meta-call>'(user:user: ...) <foreign>
ERROR: [9] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

```

Notably, why we get false in the first call.

Thanks,  
Paulo

---

<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:** [February 13, 2020, 2:23pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/2 "2020-02-13T14:23:04Z")

</div>

Functional notation is ultimately implemented by expand\_goal/2 which scans the goal arguments for A.B and turns `g(A.B)` into `.(A,B,C), g(C)`.

In the first example no expansion on the term happens, so in the end it just tries to unify A.foo with [], which fails. Note that call/1 (I think unlike SICStus) does not perform any expansion. If we want that:

```prolog
?- read(X), expand_goal(X,Y), call(Y).
|: A.foo = [].

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [14] throw(error(instantiation_error,_9142))
ERROR: [12] '$dicts':'.'(_9172,foo,_9176) at /ufs/wielemak/src/swipl-devel/linux/home/boot/dicts.pl:46
ERROR: [11] '<meta-call>'(('.'(_9220,foo,_9224),_9228=[])) <foreign>
ERROR: [10] '<meta-call>'(user:user: ...) <foreign>
ERROR: [9] <user>

```

As you probably guessed by now, the toplevel calls expand\_goal/2 on the query you typed.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [February 13, 2020, 3:01pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/3 "2020-02-13T15:01:26Z")

</div>

Thanks for the quick reply. As the documentation states that " Functions are recognised if they appear in the argument of a _goal_ in the source text, possibly nested in a term.", I was expecting the same behavior in both cases. I don’t think calling `expand_goal/2` is an option on my case, but I will research it further.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [February 13, 2020, 9:03pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/4 "2020-02-13T21:03:01Z")

</div>

> [@jan](#):
>
> Functional notation is ultimately implemented by expand\_goal/2 …

Calling either `term_expansion/2` or `goal_expansion/2` on the read term (a clause) doesn’t expand its `A.B` arguments. Tried calls in both `user` and `system` modules. What am I missing? Looked into the `boot/dicts.pl` file but the expansion rules there don’t apply to clauses.

---

<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:** [February 14, 2020, 8:08am UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/5 "2020-02-14T08:08:49Z")

</div>

expand\_goal/2 and expand\_term/2 call user goal\_expansion/2 and expand\_term/2, but end with DCG expansion and functional notation. The code is a bit of a mess and subject to change, but you find it in boot/expand.pl, replace\_functions/4.

---

<div class="post-metadata">

**Author:** ![pmoura](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/pmoura/32/11_2.png) [@pmoura](https://swi-prolog.discourse.group/u/pmoura)\
**Post date:** [February 14, 2020, 3:33pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/6 "2020-02-14T15:33:06Z")

</div>

Noticed the `expand:replace_functions/4` predicate. I was loping/looking for a way to access dict expansions independently of any other expansions **and** accessible by calling `term_expansion/2` and `goal_expansion/2` rules in a specific module. I do understand the current solution. Traditionally, DCG expansion have been implemented as a default expansion.

---

<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:** [February 14, 2020, 4:01pm UTC](https://swi-prolog.discourse.group/t/dict-access-odd-behavior/1860/7 "2020-02-14T16:01:09Z")

</div>

In due time, all of that is likely to become possible. Not yet though …
