Complete lists and not just in "abridged" form

Hello everyone!
I have a simple question to ask: how do I change the settings of the Prolog interpreter in such a way that lists are shown completely on screen and not just in their “abridged” form like in the following example?

Out = [the, old, doctor, sent, to, the251, old698, landlady, a|...].

Thanks

Could use e.g. writeln/1 or format/2 to output them. E.g.:

?- length(L, 150), writeln(L).

Can adjust the flags such as max_depth.

1 Like
?- X = [1,2,3,4,5,6,7,8,9,10].
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...].

?- current_prolog_flag(answer_write_options,X).
X = [quoted(true), portray(true), max_depth(10), spacing(next_argument)].
 
?- set_prolog_flag(answer_write_options,[quoted(true), portray(true), max_depth(20), spacing(next_argument)]).
true.

?- X = [1,2,3,4,5,6,7,8,9,10,11,12,13].
X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].

?- X = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21].
X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19|...].

See also write_term/2 (and the manual section on flags). If you set max_depth to 0, that gives you “unlimited depth”. Note that this also affects the output of complex terms.

2 Likes

If you are at the prompt between solutions you can type “w” to write the full term. If you only have a single solution add ; true to the query, like this:

?- numlist(1, 10, L) ; true.
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] [write] % I just typed "w"
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] .

You can turn it off again with “p” for print. With large terms always writing in full gets in the way. You can see the possible actions with “h” for help:

?- numlist(1, 10, L) ; true.
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
  Possible actions:
  ; (n,r,space,TAB): redo              | t:         trace&redo
  *:                 show choicepoint  | c (a,RET): stop
  w:                 write             | p:         print
  b:                 break             | h (?):     help

Action? [print]
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] .
5 Likes

It is mildly annoying in some rare cases, that writing/printing cuts off at depth. Flat terms still spam my console output. Like this query:

?- numlist(1, 9999, L), T =.. [v|L].
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
T = v(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, /* snip */
1 Like

I’ve almost never created a term with more than 10 arguments, so it would seem to be reasonable to have max_depth also govern terms (or add a max_args option). The relevant code seems to be the for-loop at pl-write.c:1782 (at the end of function writeTerm2().

Perhaps dicts should also be limited? (Although changing the code for them appears to be a bit more complicated - there’s a call to PL_for_dict() that would need an extra argument to track the how many items have been output.)

PL_for_dict() passes a pointer to some void* context object and the callback can request to stop the iteration by returning non-NULL.

I’m not sure we want even more options to write_term/3. On the other hand, using the depth limit already has some issues as applied to lists. If we have a list of lists, the sub-lists get one shorter each time. We could consider a max_args (or something like that) that would apply to lists, terms and dicts. Note that we also have long atoms and strings. We could also consider to replace ... by e.g., ...(N)... <last>, i.e., showing also the last of the set as well as the number of arguments skipped.

What of this makes sense? Or do people consider it as just complicating things for little return?

Note that portray/1 hooks can do most of these things.

Is there a way to display such useful help menu at top level query without typing the query plus “; true.” Once I tried to find but, could not.

You can use

?- set_prolog_flag(prompt_alternatives_on, groundness).

Now it prompts always if the goal is not ground and never if it is ground. That is what happened in many traditional Prolog systems. The default is to prompt if the goal succeeded with a choicepoint. The only price is that you cannot reprint the answer with other options if the predicate is deterministic, but for that we have the `; true’ :slight_smile:

1 Like

It works. Thanks. Also now I see the reason of magical use of ; true.

?- set_prolog_flag(prompt_alternatives_on, groundness).

?- numlist(1, 200, L).
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] [write]
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200] .

Thank you all for the answers. I have set max_depth to 50 which should be more than enough, but after all these suggestions I may go back to 10 to try all of these “secret” commands at the prompt I didn’t know about :sweat_smile: