# Strange warning message from compile or listing

**URL:** <https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774>\
**Category:** Help!\
**Tags:** bug\
**Created:** [March 28, 2021, 10:22pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774 "2021-03-28T22:22:24Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 28, 2021, 10:22pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/1 "2021-03-28T22:22:24Z")

</div>

I’m using: SWI-Prolog version 8.3.21

I get a weird warning message when compiling or when listing a clause. Similar clauses produce no message. And I can make the message go away by removing a `meta_predicate` directive.  
And, as far as I can tell the message is bogus (the resulting term expansion appears to be correct).

I can trace the code to `bool/expand.pl` predicate `call_goal_expansion/5`, where there’s a call to either `M:goal_expansion(G0,P0,G,P)` or `M:goal_expansion(G0,G)` … but when I single-step, all I get is the weird error message. (Question to @jan - how to trace such low-level predicates?)

This is the message from compiling (and a similar message from calling listing/1):

```prolog
Warning: /home/peter/Downloads/extended_pos_msg_bug.pl:28:
Warning: Unknown message: extended_pos(list_position(1376,1400,[term_position(1378,1398,1396,1397,[term_position(1378,1396,1386,1387,[1378-1386,1387-1396]),1397-1398])],none),7)
Warning: /home/peter/Downloads/extended_pos_msg_bug.pl:28:
Warning: Unknown message: extended_pos(list_position(1376,1400,[term_position(1378,1398,1396,1397,[term_position(1378,1396,1386,1387,[1378-1386,1387-1396]),1397-1398])],none),7)

```

I can make the message go away by removing the `meta_predicate` directive on line 16.

The code can be downloaded from [extended\_pos\_msg\_bug.pl](https://swi-prolog.discourse.group/uploads/short-url/6WBXnbb9OcNQAAeTc4YBGwymPo4.pl) (1.6 KB)

To duplicate the bug, simply download the file and run:  
`swipl extended_pos_msg_bug.pl`  
The best spy point I could find was `ci_expand`.

---

<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:** [March 29, 2021, 7:38am UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/2 "2021-03-29T07:38:35Z")

</div>

> [@peter.ludemann](#):
>
> Question to @jan - how to trace such low-level predicates

You may try using the normal debugger. As the term expansion code is used by the source level debugger it most likely gets a mess. What can also help is a couple of well placed trace/1 calls, e.g., starting with

```
?- trace('$expand':extended_pos/3).

```

Another option is to add some print/debug/… statements to the code 🙂

I don’t know really what is happening why, but the message suggests it tries to add 7 arguments to a list, i.e., turn a term `'[|]'(Head,Tail)` into `'[|]'(Head,Tail, A1, ... A7)`. I doubt that is a good idea. If this is what really should happen than `extended_pos/3` should be extended to turn the list\_position term into a term\_position term, reusing as much as possible of the info.

P.s. while `?- directive.` is still accepted I think it should be considered deprecated. I think it got there because C-Prolog had this. Any other Prolog system?

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 29, 2021, 4:01pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/4 "2021-03-29T16:01:44Z")

</div>

The problem seems to occur in some internal post-processing of the clause (hence the `extended_pos` stuff, which doesn’t occur in my term\_expansion code; and also it shows up when I use listing/1 on the predicate). It’s clearly related to adding arguments in a call/7 context (the problem goes away when I remove the `meta_predicate maplist_kyfact_symrej(7, +, -, +, -, +, -, +)` directive), but I can’t figure out where the message is produced … when I try tracing, I get to `call_goal_expansion/5`, and then the debugger jumps to outputting the message – I need a way to turn on turn on a global `generate_debug_info`. Alternatively, I’d add some print/debug statements but how do I do that for code that’s defined as part of the system? (Add the print/debug statements and rebuild?)

Anyway, I discovered `set_prolog_flag(debug_term_position, true)`, and that produced a bunch of warnings of the following form, but I’m not sure how to interpret them, nor do I understand why listing/1 would be calling term expansion.

```prolog
Layout data: expected f1, found: [term_position(2351,2472,2351,2353,[term_position(2354,2472,2354,2371,[term_position(2372,2386,2384,2385,[2372-2384,2385-2386]),2388-2389,list_position(2412,2471,[term_position(2414,2448,2414,2421,[term_position(2422,2444,2428,2429,[2422-2428,term_position(2429,2444,2442,2443,[2429-2442,2443-2444])]),2446-2447])],none)])]),term_position(2351,2472,2351,2353,[term_position(2354,2472,2354,2371,[term_position(2372,2386,2384,2385,[2372-2384,2385-2386]),2388-2389,list_position(2412,2471,[term_position(2414,2448,2414,2421,[term_position(2422,2444,2428,2429,[2422-2428,term_position(2429,2444,2442,2443,[2429-2442,2443-2444])]),2446-2447])],none)])]),term_position(2351,2472,2351,2353,[term_position(2354,2472,2354,2371,[term_position(2372,2386,2384,2385,[2372-2384,2385-2386]),2388-2389,list_position(2412,2471,[term_position(2414,2448,2414,2421,[term_position(2422,2444,2428,2429,[2422-2428,term_position(2429,2444,2442,2443,[2429-2442,2443-2444])]),2446-2447])],none)])])]

```

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 29, 2021, 4:04pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/5 "2021-03-29T16:04:27Z")

</div>

> [@jan](#):
>
> while `?- directive.` is still accepted I think it should be considered deprecated

I used that in the posted code to ensure that if someone tries to reproduce the bug, they have the correct SWI-Prolog and EDCG versions. Is there a better way of doing this than adding a `?-` that throws an error?

---

<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:** [March 29, 2021, 6:30pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/6 "2021-03-29T18:30:22Z")

</div>

> [@peter.ludemann](#):
>
> Alternatively, I’d add some print/debug statements but how do I do that for code that’s defined as part of the system? (Add the print/debug statements and rebuild?)

Mostly. If you build from source, the quickest way to get going again is edit the source and run

```
 ninja core

```

Now you can run `src/swipl` to run the new version. No need to install. The position management is really hard. I tried to write a new approach to this, but it never materialized and I’m too busy now.

**edit** to some extend you can trace the stuff (using the commandline tracer) after setting the flag below. YMMV though, It is easy enough to cause the debugger eating its own tail 🙂

```
?- set_prolog_flag(access_level, system).

```

---

<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:** [March 29, 2021, 6:35pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/7 "2021-03-29T18:35:18Z")

</div>

> [@peter.ludemann](#):
>
> Is there a better way of doing this than adding a `?-` that throws an error?

AFAIK the ISO standard dictates `:- Directive`, were directives are things defined by the language and `:- initialization(Goal)` can be used to run initialization tasks. SWI-Prolog has no special “directive” class. All directives are goals and `:- dynamic p/1.` thus simply executes dynamic/1. The only implication of initialization is that, conform ISO, the goal is executed after loading the file has completed rather than immediately. `?- Goal.` is, AFAIK, something from the old days.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 30, 2021, 12:29am UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/8 "2021-03-30T00:29:39Z")

</div>

I’ve sent a patch to @jan , but I’m not convinced it’s a correct solution. It appears that term expansion is being applied to a read-in-term, but it’s become confused about where it is.

Specifically, when compiling (or listing this code:

```prolog
eval_assign_dot_op_binds_single(RightEval, astn(Start,End,AttrName), _BindsLeft, function_type(FunctionName,Params, Return)) ==>>
    eval_union_type(Return, _),
    maplist_kyfact_symrej(eval_union_type, Params, _),
    { join_fqn([FunctionName, AttrName], BindsFqn) },
    [BindsFqn-RightEval-_]:symrej,
    kyanchor_binding(Start,End, AttrName, BindsFqn, FunctionName, 'eval_assign_dot_op_binds_single/function_type').

```

goal expansion seems to be working on `eval_union_type(Return, _)` but extended\_pos/3 is trying to handle `[BindsFqn-RightEval-_]:symrej`. (For listing/1, there’s  
a call to prolog\_clause:clause\_info/5,  
which calls prolog\_clause:unify\_clause/5,  
which calls proloog\_clause:ci\_expand/5,  
which calls expand\_term/3,  
which fails; but it produces a spurious warning message from extended\_pos/3 along the way.

(The presence of a meta-predicate declaration changes some of the term expansion behavior, which appears to be why removing it makes the error message go away … but this seems to be yet another variation of how term expansion is confused about its position in the term.)

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 30, 2021, 7:01pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/9 "2021-03-30T19:01:27Z")

</div>

@jan has rejected my patch – correctly so (it was solving the wrong problem).

The solution seems to be in modifying EDCG term expansion. In the meantime, I have silenced the message by:

```prolog
:- multifile user:message_hook/3.
:- dynamic user:message_hook/3.

user:message_hook(extended_pos(_Pos, _N), warning, Lines) :-
    Lines = ['Unknown message: ~p'-_],
    % user:message_hook(extended_pos(_Pos, _N), informational, _Lines).
    true. % suppress this message.

```

For future reference, here’s Jan’s reply to me:

> [@](#):
>
> … The position management is clearly already mixed up as we see this term/position pair
> 
> ```
> eval_union_type,list_position(1376,1400,[...],none)
> 
> ```
> 
> An atom should have Start-End as position rather than a list.
> 
> My first hypothesis is that your expansion does a bit too much rewriting of the term and you should be using the /4 versions of the expansion predicates to convert the source layout along with the term itself.
> 
> This is extremely nasty stuff. I’ve been working on a better solution, basically doing the layout transformation automatically by tracking “anchor” terms that are not modified and fill in the  
> details. Unfortunately that stalled and I’m too busy to pick that up again.
> 
> I think you can use term\_expansion/4 and/or goal\_expansion/2 and simply return a variable as new term position, telling the system “I don’t know”. Of course that kills the source level debugger and source level errors and warnings.

For me, the marginal value of improving this is very low – I seldom use the source-level tracing, and it’s “good enough” for me without the fancier term expansion that figures out variable names. But it’s probably worth modifying EDCG to use term\_expansion/4 and return a “I don’t know” value.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [March 30, 2021, 8:58pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/10 "2021-03-30T20:58:41Z")

</div>

I’ve updated EDCG pack, following Jan’s suggestion. (And now I understand the var/1 tests in `expand.pl`).

---

<div class="post-metadata">

**Author:** ![oskardrums](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/oskardrums/32/3594_2.png) [@oskardrums](https://swi-prolog.discourse.group/u/oskardrums)\
**Post date:** [July 24, 2021, 7:24pm UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/11 "2021-07-24T19:24:56Z")

</div>

Hey,  
FYI I’ve hit this issue with SWI-Prolog version 8.3.27 as well.  
It can be reproduced with the following module:

```prolog
$ cat term_expansion_warning.pl
:- module(term_expansion_warning, [op(1200, xfx, <^>)]).

user:term_expansion((L <^> R0), (L --> R)) :-
    lift(R0, R).

lift(L, l(L)) :- is_list(L), !.
lift(','(H0, T0), ','(H, T)) :- lift(H0, H), lift(T0, T), !.
lift(R, R).

foo <^> [1].

```

When compiling or listing/1 foo there’s a warning although the term expansion seems to work fine:

```prolog
$ swipl term_expansion_warning.pl
Warning: /tmp/term_expansion_warning.pl:10:
Warning: Unknown message: extended_pos(list_position(236,239,[237-238],none),2)
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.27)
...

?- listing(term_expansion_warning:foo).
Warning: Unknown message: extended_pos(list_position(236,239,[237-238],none),2)
foo(A, B) :-
    l([1], A, B).

true.

```

To get rid of the warning I used the same solution suggested above, and replaced

```prolog
user:term_expansion((L <^> R0), (L --> R)) :- lift(R0, R).

```

with

```prolog
user:term_expansion((L <^> R0), _Layout0, (L --> R), _Layout) :- lift(R0, R).

```

Cheers 🙂

---

<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 26, 2021, 8:44am UTC](https://swi-prolog.discourse.group/t/strange-warning-message-from-compile-or-listing/3774/12 "2021-07-26T08:44:10Z")

</div>

The problem is that `foo <^> [1]` becomes `foo --> l([1])`, while the position information for the right hand is not updated. Now, DCG expansion adds two arguments to l/1, but the position information is that for a list and adding arguments to a list position term is not defined. If you want this to work, the trick is to use term\_expansion/4 and wrap the list position term into one that you create for the l/1 term. What you do works as well, as it effectively destroys the position information. As a result the source level debugger doesn’t work for this clause.
