Q on aggregate_all/*

155 views
Skip to first unread message

Julio Di Egidio

unread,
May 17, 2015, 4:49:35 PM5/17/15
to swi-p...@googlegroups.com
Hi guys,

In swipl 6.6.6, aggregate_all/* are marked semidet in the docs, but I cannot find a scenario where they fail:

?- findall(_,fail,L).
L = [].

?- aggregate_all(count,fail,C).
C = 0.

?- aggregate_all(c,fail,C).
ERROR: Type error: `aggregate_template' expected, found `c'

What am I missing?  :)

Thank you,

Julio

Kilian Evang

unread,
May 17, 2015, 6:20:02 PM5/17/15
to swi-p...@googlegroups.com
Interesting question! I found one scenario: if you try to find the minimum or maximum of an empty set.

?- dynamic c/1.
true.

?- aggregate_all(max(X), c(X), Max).
false.

Julio Di Egidio

unread,
May 17, 2015, 7:17:11 PM5/17/15
to swi-p...@googlegroups.com
Thank you, Kilian, interesting find...

Julio

Julio Di Egidio

unread,
May 17, 2015, 10:19:25 PM5/17/15
to swi-p...@googlegroups.com
Few more examples:

?- aggregate_all(count,between(1,2,_),C).
C
= 2.

?- aggregate_all(count,between(1,2,_),2).
true.

?- aggregate_all(count,between(1,2,_),1).
false.

?- aggregate_all(count,between(1,2,_),a).
false.

?- aggregate_all(count,false,C).
C
= 0.

?- aggregate_all(count,false,0).
true.

?- aggregate_all(count,false,1).
false.

?- aggregate_all(count,false,a).
false.

Case closed as far as I can see.

Cheers,

Julio

Julio Di Egidio

unread,
May 18, 2015, 12:46:59 AM5/18/15
to swi-p...@googlegroups.com
Hi back, sorry, still thinking about this...

The declaration of aggregate_all/3 in the docs is:

  aggregate_all(+T, :G, -R)  [semidet]

Given the examples up-thread, isn't this one is more correct?

  aggregate_all(+T, :G, -R)  [det]
  aggregate_all(+T, :G, +R)  [semidet]

Is someone, maybe Jan, able to confirm how it works?

Julio

Jan Wielemaker

unread,
May 18, 2015, 2:47:15 AM5/18/15
to Julio Di Egidio, swi-p...@googlegroups.com
On 18-05-15 04:19, Julio Di Egidio wrote:
> Few more examples:
>
> |
> ?-aggregate_all(count,between(1,2,_),C).
> C =2.
>
> ?-aggregate_all(count,between(1,2,_),2).
> true.
>
> ?-aggregate_all(count,between(1,2,_),1).
> false.

This is not a reason not to be det. The mode gives
`-` for the last argument. Det would mean it
succeeds, _given that the last argument is
unbound_. The behaviour with a bound argument
is that of

aggregate_all(count,between(1,2,_),C), C = 1.

This is (supposed to be) the case for all arguments
with mode `-`. Well, except for e.g., open/3, where
the last argument _must be unbound_ or else an
uninstantiation error is raised. This is because
you cannot meaningfully compare with a created
stream.

Cheers --- Jan

Jan Wielemaker

unread,
May 18, 2015, 2:56:14 AM5/18/15
to Julio Di Egidio, swi-p...@googlegroups.com
On 18-05-15 06:46, Julio Di Egidio wrote:
>
> aggregate_all(+T, :G, -R) [det]
> aggregate_all(+T, :G, +R) [semidet]
>
> Is someone, maybe Jan, able to confirm how it works?

See my previous reply. If you do the above, you have
to repeat that for all predicates with mode `-` in some
arguments. That isn't really helpful. Only predicates
that have no output arguments can guarantee to succeed
_always_, given acceptable input arguments. There are
few examples of these :-) `true` and the output (write)
predicates are among the few examples I can think of.

Cheers --- Jan

Julio Di Egidio

unread,
May 19, 2015, 9:20:41 AM5/19/15
to swi-p...@googlegroups.com, ju...@diegidio.name
On Monday, May 18, 2015 at 7:47:15 AM UTC+1, Jan Wielemaker wrote:
On 18-05-15 04:19, Julio Di Egidio wrote:
> Few more examples:
>
> ?-aggregate_all(count,between(1,2,_),C).
> C =2.
>
> ?-aggregate_all(count,between(1,2,_),2).
> true.
>
> ?-aggregate_all(count,between(1,2,_),1).
> false.

This is not a reason not to be det.  The mode gives
`-` for the last argument.  Det would mean it
succeeds, _given that the last argument is
unbound_.

Isn't that exactly correct, that it always succeeds with unbound last argument?
 
 The behaviour with a bound argument
is that of

    aggregate_all(count,between(1,2,_),C), C = 1.

This is (supposed to be) the case for all arguments
with mode `-`.

I do not understand that: it is C=1 that is failing there, not aggregate_all  (But don't get me wrong: I know there is a long history with these conventions, I just still get confused and do not yet grasp whether it is me or Prolog a bit messy here...)
 
 Well, except for e.g., open/3, where
the last argument _must be unbound_

Indeed, when I see "-", I take it that the argument *must* be unbound, that was the point!

Julio

Julio Di Egidio

unread,
May 19, 2015, 9:38:46 AM5/19/15
to swi-p...@googlegroups.com, ju...@diegidio.name
On Monday, May 18, 2015 at 7:56:14 AM UTC+1, Jan Wielemaker wrote:
On 18-05-15 06:46, Julio Di Egidio wrote:
>
>    aggregate_all(+T, :G, -R)  [det]
>    aggregate_all(+T, :G, +R)  [semidet]
>
> Is someone, maybe Jan, able to confirm how it works?

See my previous reply.  If you do the above, you have
to repeat that for all predicates with mode `-` in some
arguments.  That isn't really helpful.

I could understand it is inconvenient, but bugs in the documentation are rather a disaster...
 
 Only predicates
that have no output arguments can guarantee to succeed
_always_, given acceptable input arguments.  There are
few examples of these :-)  `true` and the output (write)
predicates are among the few examples I can think of.

(I am not the expert, but) not to clutter the docs yet have it correct, I'd have written:

    aggregate_all(+T, :G, ?R)  [semidet]

Julio

Jan Wielemaker

unread,
May 19, 2015, 9:50:53 AM5/19/15
to Julio Di Egidio, swi-p...@googlegroups.com
On 05/19/2015 03:38 PM, Julio Di Egidio wrote:
> On Monday, May 18, 2015 at 7:56:14 AM UTC+1, Jan Wielemaker wrote:
>
> On 18-05-15 06:46, Julio Di Egidio wrote:
> >
> > aggregate_all(+T, :G, -R) [det]
> > aggregate_all(+T, :G, +R) [semidet]
> >
> > Is someone, maybe Jan, able to confirm how it works?
>
> See my previous reply. If you do the above, you have
> to repeat that for all predicates with mode `-` in some
> arguments. That isn't really helpful.
>
>
> I could understand it is inconvenient, but bugs in the documentation are
> rather a disaster...

There is no bug in the documentation. Given a predicate x with
an argument with mode `-`, e.g., x(-) the determinism applies to
the case where the output argument is unbound. If x/1 is used
with a bound argument (Value below), the semantics is defined as:

`x(Value)` is same as `x(Result), Result = Value`

The latter is obviously semidet as `Result = Value` can fail.

E.g., although findall/3 is det, it the following is perfectly
legal and generally good style to get the first two solutions
of a goal:

findall(X, x(X), [X1,X2|_]).

Thus is the same as

findall(X, x(X), Xs), Xs = [X1,X2|_].

which may obviously fail if there are less than two answers
for x(X).

Cheers --- Jan

P.s. Giving a value to an output (`-`) argument is actually
good style. It is not only more compact, but also
allows the predicate to optimise. For example,
term_attvars(Term, []) is an efficient way to prove
that Term has *no* attributed variables. The implementation
checks for this pattern and fails as soon as it found the
first attributed variable in Term.

>
> Only predicates
> that have no output arguments can guarantee to succeed
> _always_, given acceptable input arguments. There are
> few examples of these :-) `true` and the output (write)
> predicates are among the few examples I can think of.
>
>
> (I am not the expert, but) not to clutter the docs yet have it correct,
> I'd have written:
>
> aggregate_all(+T, :G, ?R) [semidet]
>
> Julio
>
> --
> You received this message because you are subscribed to the Google
> Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to swi-prolog+...@googlegroups.com
> <mailto:swi-prolog+...@googlegroups.com>.
> Visit this group at http://groups.google.com/group/swi-prolog.
> For more options, visit https://groups.google.com/d/optout.

Kilian Evang

unread,
May 19, 2015, 10:03:05 AM5/19/15
to swi-p...@googlegroups.com


On Tuesday, May 19, 2015 at 3:20:41 PM UTC+2, Julio Di Egidio wrote:
On Monday, May 18, 2015 at 7:47:15 AM UTC+1, Jan Wielemaker wrote:
On 18-05-15 04:19, Julio Di Egidio wrote:
> Few more examples:
>
> ?-aggregate_all(count,between(1,2,_),C).
> C =2.
>
> ?-aggregate_all(count,between(1,2,_),2).
> true.
>
> ?-aggregate_all(count,between(1,2,_),1).
> false.

This is not a reason not to be det.  The mode gives
`-` for the last argument.  Det would mean it
succeeds, _given that the last argument is
unbound_.

Isn't that exactly correct, that it always succeeds with unbound last argument?

No. Remember my example with max?

Kilian Evang

unread,
May 19, 2015, 10:09:04 AM5/19/15
to swi-p...@googlegroups.com, ju...@diegidio.name


On Tuesday, May 19, 2015 at 3:50:53 PM UTC+2, Jan Wielemaker wrote:
Given a predicate x with
an argument with mode `-`, e.g., x(-) the determinism applies to
the case where the output argument is unbound.  If x/1 is used
with a bound argument (Value below), the semantics is defined as:

        `x(Value)` is same as `x(Result), Result = Value`

So you're saying a mode declaration containing a `-` makes the guarantee that it behaves like that if called with that argument bound? Is this documented anywhere?

Julio Di Egidio

unread,
May 19, 2015, 10:11:20 AM5/19/15
to swi-p...@googlegroups.com
Yes, and my guess is that it is a bug... somewhere, the docs being the first candidate.  (But I'm busy now: I'll have to follow up later.)

Julio

Kilian Evang

unread,
May 19, 2015, 10:19:19 AM5/19/15
to swi-p...@googlegroups.com

It's not. Mathematically, the minimum or maximum of an empty set is not defined, so it makes perfect sense for this goal to fail. And the docs correctly state it's semidet.

Jan Wielemaker

unread,
May 19, 2015, 10:23:36 AM5/19/15
to Kilian Evang, swi-p...@googlegroups.com
On 05/19/2015 04:19 PM, Kilian Evang wrote:
>
> Yes, and my guess is that it is a bug... somewhere, the docs being
> the first candidate. (But I'm busy now: I'll have to follow up later.)
>
>
> It's not. Mathematically, the minimum or maximum of an empty set is not
> defined, so it makes perfect sense for this goal to fail. And the docs
> correctly state it's semidet.

Yip. Might be wise to add a sentence to the docs about this. It is
also unclear whether failure is a good idea here or whether an exception
might be better. I don't have SICStus anymore, so I cannot compare with
their version. Anyone?

Cheers --- Jan

Kilian Evang

unread,
May 19, 2015, 10:30:20 AM5/19/15
to swi-p...@googlegroups.com, maschi...@texttheater.net

It also fails:

SICStus 4.2.3 (x86_64-linux-glibc2.7): Fri Oct  5 15:52:44 CEST 2012
Licensed to SP4 Kilian Evang on Linux
| ?- use_module(library(aggregate)).
% loading /home/p264360/opt/sicstus4/bin/sp-4.2.3/sicstus-4.2.3/library/aggregate.po...
% module aggregate imported into user
%  loading /home/p264360/opt/sicstus4/bin/sp-4.2.3/sicstus-4.2.3/library/types.po...
%  module types imported into aggregate
%  loaded /home/p264360/opt/sicstus4/bin/sp-4.2.3/sicstus-4.2.3/library/types.po in module types, 0 msec 1424 bytes
% loaded /home/p264360/opt/sicstus4/bin/sp-4.2.3/sicstus-4.2.3/library/aggregate.po in module aggregate, 0 msec 41840 bytes
yes
| ?- assertz(a(1)).
yes
| ?- aggregate_all(max(X), a(X), Max).
Max = 1 ? ;
no
| ?- retract(a(_)).
yes
| ?- aggregate_all(max(X), a(X), Max).
no
| ?- 
 

Jan Wielemaker

unread,
May 19, 2015, 10:46:31 AM5/19/15
to Kilian Evang, swi-p...@googlegroups.com
On 05/19/2015 04:30 PM, Kilian Evang wrote:
> | ?- assertz(a(1)).
> yes
> | ?- aggregate_all(max(X), a(X), Max).
> Max = 1 ? ;
> no
> | ?- retract(a(_)).
> yes
> | ?- aggregate_all(max(X), a(X), Max).
> no
> | ?-

Thanks. Added a sentence to the docs explaining this.

Cheers --- Jan

Julio Di Egidio

unread,
May 20, 2015, 12:09:35 PM5/20/15
to swi-p...@googlegroups.com
I beg to disagree: the docs are indeed the culprit, but the problem is not that it is marked semidet, the problem is that -R should be ?R.

Julio

Julio Di Egidio

unread,
May 20, 2015, 12:23:40 PM5/20/15
to swi-p...@googlegroups.com, ju...@diegidio.name
On Monday, May 18, 2015 at 7:47:15 AM UTC+1, Jan Wielemaker wrote:
Just to clarify, this had started as a purely technical question: I am writing some code and I need my predicate, which uses aggregate_all/3, to be det.  So, if I had to trust the docs for what they just state, I should code defensively...  Then you have clarified that with unbound last argument aggregate_all/3 does indeed always succeed, which is what I needed to know: just, of course, it is not ideal that I have to rely on your personal knowledge (or digging into the source code myself), always with the possibility that things break just tomorrow, and so on.  But my question was answered.

That said, I do have an objection to the swipl documentation: namely, I vaguely recollect now that there are essentially two philosophies in Prolog as to how to specify predicate modes, and SWI adopts the convention that I find less effective if not (frankly, but aware I am not an expert) just broken...  And the *ambiguities* you yourself have pointed out in this thread are enough to prove my point...  If you are interested, I could elaborate further, e.g. on that -R vs. ?R, and how your example of the aggregate_all(T,G,C), C=1 rather proves my point, not yours.  But only if you are interested: as said my question has been answered, not to mention that I do love swipl and, as a seasoned software professional, I can very well imagine how much work there is behind it...

Julio

Boris Vassilev

unread,
May 20, 2015, 12:38:06 PM5/20/15
to Julio Di Egidio, swi-p...@googlegroups.com
One needs a lot of implicit knowledge to read the SWI-Prolog documentation, or any Prolog implementation documentation, or any documentation, or any text, for that matter (and so on).

The issue of -R vs ?R confused me too once (I tried to dig up the conversation with Jan but I don't remember the context, so I couldn't find it).

Would it be worth the effort to shortly discuss the issue in the documentation of PlDoc?

http://www.swi-prolog.org/pldoc/man?section=modes

If I remember correctly, the original source of my confusion was:

Instantiation patterns are:
...
- : argument must be unbound
...

I still think it is better to leave things as they are, but explaining this "gotcha" might be helpful.

Cheers,
Boris



Currently in the EET time zone: This is UTC +2:00 (and I sleep at night)
Save our in-boxes! http://emailcharter.org

--
You received this message because you are subscribed to the Google Groups "SWI-Prolog" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swi-prolog+...@googlegroups.com.

Julio Di Egidio

unread,
May 20, 2015, 12:49:47 PM5/20/15
to swi-p...@googlegroups.com, ju...@diegidio.name

On Wednesday, May 20, 2015 at 5:38:06 PM UTC+1, boris.vassilev wrote:

One needs a lot of implicit knowledge to read the SWI-Prolog documentation, or any Prolog implementation documentation, or any documentation, or any text, for that matter (and so on).

Not true: documentation can be complete and unambiguous, in fact *correct*.  ("Complete" is a delicate one, but can be done too, one has to know how to "close holes".)
 
The issue of -R vs ?R confused me too once (I tried to dig up the conversation with Jan but I don't remember the context, so I couldn't find it).

Would it be worth the effort to shortly discuss the issue in the documentation of PlDoc?

http://www.swi-prolog.org/pldoc/man?section=modes

It is indeed not what it does (at least in many places): but I'll let others comment further.

Julio

Jan Wielemaker

unread,
May 20, 2015, 1:21:38 PM5/20/15
to Boris Vassilev, Julio Di Egidio, swi-p...@googlegroups.com
On 05/20/2015 06:37 PM, Boris Vassilev wrote:
> One needs a lot of implicit knowledge to read the SWI-Prolog
> documentation, or any Prolog implementation documentation, or any
> documentation, or any text, for that matter (and so on).
>
> The issue of -R vs ?R confused me too once (I tried to dig up the
> conversation with Jan but I don't remember the context, so I couldn't
> find it).
>
> Would it be worth the effort to shortly discuss the issue in the
> documentation of PlDoc?
>
> http://www.swi-prolog.org/pldoc/man?section=modes
>
> If I remember correctly, the original source of my confusion was:
>
> Instantiation patterns are:
> ...
> - : argument must be unbound
> ...
>
> I still think it is better to leave things as they are, but explaining
> this "gotcha" might be helpful.

I agree. The above should be fixed. The mode `-` as "argument must be
unbound"
is pretty meaningless as there are probably not more than a handful of
predicates
for which this applies. Typically, these are predicates that generate some
unpredictable result, e.g., returning a unique handle to something created.

In more formal mode system proposals we see `--` for that (and `++` for
ground).

The `?` mode somehow affects the computation further than just unifying the
result when instantiated.

Possibly we should add `--` to the documentation and document their
difference?

Cheers --- Jan

Anne Ogborn

unread,
May 21, 2015, 6:08:14 AM5/21/15
to Julio Di Egidio, swi-p...@googlegroups.com
This seems like a great moment to mention that if you find the documentation lacking, one of the best responses is
to add a comment to the page explaining your confusion, and add the doc-needs-help tag to the page.

An even better response is to research the point of confusion, edit the source comment to clarify it, and send Jan a patch. 8cD

::Annie is here, slapping a duck tape patch on a duck::

::All the non-Americans are here, scratching their heads and wondering if there's really such a thing as duck tape. Those who are aware there is such a thing are wondering what the deal is with Americans and their love of duck tape::

Jan Wielemaker

unread,
May 21, 2015, 6:23:43 AM5/21/15
to Anne Ogborn, Julio Di Egidio, swi-p...@googlegroups.com
On 05/21/2015 12:06 PM, Anne Ogborn wrote:
> This seems like a great moment to mention that if you find the
> documentation lacking, one of the best responses is to add a comment
> to the page explaining your confusion, and add the doc-needs-help tag
> to the page.

That helps. Somehow we need a way to fix the docs though and keep
some acknowledgement. I still don't know how to do that.

- Should we simply delete the comment after the docs have
been enhanced? That is clean, but might make the contributor
unhappy.
- Mark them as `closed' and provide some way to show closed
comments?

We also need a way to comment on comments (I think). Some of the
comments are dubious ... Suggestions welcome. Willing to hack a
little even more :-)

Just a "doc-needs-help" gives some indication, but quite often I'm
pretty puzzled about what is unclear. Of course, some people cannot
read the docs because they are not aware of Prolog's terminology and
the documentation conventions. Possibly we need an obvious link to
a bluffers guide on how to read the manual? We could also link
Prolog terminology to the (already existing) glossary?

> An even better response is to research the point of confusion, edit
> the source comment to clarify it, and send Jan a patch. 8cD

I love those! Even more as git formatted patches or github pull
requests.

> ::Annie is here, slapping a duck tape patch on a duck::

:-) I though it was called "duct" tape, no?

Cheers --- Jan

Paulo Moura

unread,
May 21, 2015, 6:30:13 AM5/21/15
to Jan Wielemaker, Boris Vassilev, Julio Di Egidio, swi-p...@googlegroups.com

> On 20/05/2015, at 18:21, Jan Wielemaker <J.Wiel...@vu.nl> wrote:
>
> On 05/20/2015 06:37 PM, Boris Vassilev wrote:
>> One needs a lot of implicit knowledge to read the SWI-Prolog
>> documentation, or any Prolog implementation documentation, or any
>> documentation, or any text, for that matter (and so on).
>>
>> The issue of -R vs ?R confused me too once (I tried to dig up the
>> conversation with Jan but I don't remember the context, so I couldn't
>> find it).
>>
>> Would it be worth the effort to shortly discuss the issue in the
>> documentation of PlDoc?
>>
>> http://www.swi-prolog.org/pldoc/man?section=modes
>>
>> If I remember correctly, the original source of my confusion was:
>>
>> Instantiation patterns are:
>> ...
>> - : argument must be unbound
>> …

*must* is the misleading bit. When used in predicate templates, we want to tell the programmer what is to be *expected* *when* the argument is unbound. Predicates can have multiple templates and behave differently (e.g. regarding the number of solutions) when an argument is bound or unbound.

Consider as an example the specification of the standard atom_concat/3 predicate:

atom_concat(?atom, ?atom, +atom)
atom_concat(+atom, +atom, -atom)

In the second template, we’re *not* specifying that the third argument must be unbound when the first two argument are bound (that would conflict with the first template!). If we couple these template and modes specs with determinism information, we’re providing useful information to the programmer. In this case, that calls using the second template will succeed deterministically.

>> I still think it is better to leave things as they are, but explaining
>> this "gotcha" might be helpful.
>
> I agree. The above should be fixed. The mode `-` as "argument must be
> unbound"
> is pretty meaningless as there are probably not more than a handful of
> predicates
> for which this applies. Typically, these are predicates that generate some
> unpredictable result, e.g., returning a unique handle to something created.
>
> In more formal mode system proposals we see `--` for that (and `++` for
> ground).
>
> The `?` mode somehow affects the computation further than just unifying the
> result when instantiated.
>
> Possibly we should add `--` to the documentation and document their
> difference?

That would indeed allow us to distinguish between the case above and other cases such as open/3 where indeed the stream argument must be unbound. As, as you mention, the cases where an argument must be unbound are rare, it makes sense to introduce a new mode indicator for these cases and keep using “-“ for the most common case where it means *if* this argument is unbound, *then* expect this predicate behavior.

Cheers,

Paulo

-----------------------------------------------------------------
Paulo Moura
Logtalk developer

Email: <mailto:pmo...@logtalk.org>
Web: <http://logtalk.org/>
-----------------------------------------------------------------




Paulo Moura

unread,
May 21, 2015, 6:46:52 AM5/21/15
to Jan Wielemaker, Anne Ogborn, Julio Di Egidio, swi-p...@googlegroups.com
Hi Jan,

> On 21/05/2015, at 11:23, Jan Wielemaker <J.Wiel...@vu.nl> wrote:
>
> On 05/21/2015 12:06 PM, Anne Ogborn wrote:
>> This seems like a great moment to mention that if you find the
>> documentation lacking, one of the best responses is to add a comment
>> to the page explaining your confusion, and add the doc-needs-help tag
>> to the page.
>
> That helps. Somehow we need a way to fix the docs though and keep
> some acknowledgement. I still don't know how to do that.
>
> - Should we simply delete the comment after the docs have
> been enhanced? That is clean, but might make the contributor
> unhappy.
> - Mark them as `closed' and provide some way to show closed
> comments?
>
> We also need a way to comment on comments (I think). Some of the
> comments are dubious ... Suggestions welcome. Willing to hack a
> little even more :-)
>
> Just a "doc-needs-help" gives some indication, but quite often I'm
> pretty puzzled about what is unclear. Of course, some people cannot
> read the docs because they are not aware of Prolog's terminology and
> the documentation conventions. Possibly we need an obvious link to
> a bluffers guide on how to read the manual? We could also link
> Prolog terminology to the (already existing) glossary?

I often link e.g. Logtalk built-in predicates documentation to a glossary as I found very earlier that greatly helps avoiding misunderstandings. This is just not an issue with novice programmers. Plenty of terminology is overloaded across programming languages with different meanings depending on the context. But a glossary is helpful even in the context of a single language, specially for concepts that are not commonly found elsewhere (e.g. “unification”, “choice-point”).

A Prolog glossary would be an ideal resource to be shared among systems. Maybe using a wiki that anyone could link to?

Cheers,

Paulo


>> An even better response is to research the point of confusion, edit
>> the source comment to clarify it, and send Jan a patch. 8cD
>
> I love those! Even more as git formatted patches or github pull
> requests.
>
>> ::Annie is here, slapping a duck tape patch on a duck::
>
> :-) I though it was called "duct" tape, no?
>
> Cheers --- Jan
>
>> ::All the non-Americans are here, scratching their heads and
>> wondering if there's really such a thing as duck tape. Those who are
>> aware there is such a thing are wondering what the deal is with
>> Americans and their love of duck tape::
>
>
> --
> You received this message because you are subscribed to the Google Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to swi-prolog+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/swi-prolog.
> For more options, visit https://groups.google.com/d/optout.

Jan Wielemaker

unread,
May 21, 2015, 8:09:22 AM5/21/15
to Paulo Moura, Anne Ogborn, Julio Di Egidio, swi-p...@googlegroups.com
Would be nice. For a start, we have
http://www.swi-prolog.org/pldoc/man?section=glossary. Probably the way
to go is to make an server
that serves a single glossary term and a little bit of JavaScript
code to link the glossary terms ...

Cheers --- Jan

Boris Vassilev

unread,
May 21, 2015, 8:25:30 AM5/21/15
to Jan Wielemaker, swi-p...@googlegroups.com
A remark about the comments:

currently, they seem to belong to "sections", and individual predicates count as sections. What this leads to is that if one is reading the predicate documentation in context, there is no indication that there are any comments. And since there is no direct link, to get to the comments, the easy way seems to be to use the search bar to jump to the documentation of that predicate only to see if there are any comments.

Question: is there a meaningful way to put comments to (sub)sections "inline"?

Somewhat orthogonal: is it reasonable to make section headers (when displayed in their context) a link to the page that only displays that single section?

Currently in the EET time zone: This is UTC +2:00 (and I sleep at night)
Save our in-boxes! http://emailcharter.org

Jan Wielemaker

unread,
May 21, 2015, 9:10:18 AM5/21/15
to Boris Vassilev, swi-p...@googlegroups.com
On 05/21/2015 02:24 PM, Boris Vassilev wrote:
> A remark about the comments:
>
> currently, they seem to belong to "sections", and individual predicates
> count as sections. What this leads to is that if one is reading the
> predicate documentation in context, there is no indication that there
> are any comments. And since there is no direct link, to get to the
> comments, the easy way seems to be to use the search bar to jump to the
> documentation of that predicate only to see if there are any comments.
>
> Question: is there a meaningful way to put comments to (sub)sections
> "inline"?

It is not impossible. Requires significant restructing of the page
DOM though.

> Somewhat orthogonal: is it reasonable to make section headers (when
> displayed in their context) a link to the page that only displays that
> single section?

That is surely easier. Might be combined with another long standing
wish: be able to jump to the sources for any Prolog-defined predicate
(ideally also the C-defined ones, but that is a bit harder :-) That now
only works for PlDoc pages, not for predicates documented in the manual.

Cheers --- Jan

Jan Wielemaker

unread,
May 21, 2015, 9:15:06 AM5/21/15
to Paulo Moura, Boris Vassilev, Julio Di Egidio, swi-p...@googlegroups.com
On 05/21/2015 12:30 PM, Paulo Moura wrote:
>>> In more formal mode system proposals we see `--` for that (and
>>> `++` for ground).
>>>
>>> The `?` mode somehow affects the computation further than just
>>> unifying the result when instantiated.
>>>
>>> Possibly we should add `--` to the documentation and document
>>> their difference?
>
> That would indeed allow us to distinguish between the case above and
> other cases such as open/3 where indeed the stream argument must be
> unbound. As, as you mention, the cases where an argument must be
> unbound are rare, it makes sense to introduce a new mode indicator
> for these cases and keep using “-“ for the most common case where it
> means*if* this argument is unbound,*then* expect this predicate
> behavior.

Added -- and ++ to PlDoc as well as the LaTeX based toolchain for
generating the manuals. See [1], starting at line 19 for the
updated description (this text is now repeated in the PlDoc
manual).

Thanks --- Jan

[1] https://github.com/SWI-Prolog/swipl-devel/blob/master/man/builtin.doc

Anne Ogborn

unread,
May 21, 2015, 6:38:25 PM5/21/15
to Jan Wielemaker, Paulo Moura, Julio Di Egidio, swi-p...@googlegroups.com
It would be very neat if you could edit the actual header comments on the website.

I'm sure many folks have been puzzled by something, figured it out, but didn't feel like checking out from github, doing actual fix, building, testing... it's a long awkward cycle if it's not something you're set up to do.

Lowering that bar to 'fix the comment on the website' in SWISH or some such and then clicking 'submit as patch' would lower it.

Of course, this means somebody volunteers to write that...

::Annie looks around at suddenly empty room::

Anne Ogborn

unread,
May 21, 2015, 6:42:06 PM5/21/15
to Jan Wielemaker, Julio Di Egidio, swi-p...@googlegroups.com


> ::Annie is here, slapping a duck tape patch on a duck::

:-) I though it was called "duct" tape, no?

Cheers --- Jan


Well, it started life that way, but after people started calling it duck tape (rural people in US swallow final consonants) somebody started marketing the tape under the Duck brand, and now it's all duck tape.

Kilian Evang

unread,
May 22, 2015, 6:48:03 AM5/22/15
to swi-p...@googlegroups.com, boris.v...@gmail.com, ju...@diegidio.name, pjlm...@gmail.com
I took a shot clarifying things further, pull request here: https://github.com/SWI-Prolog/packages-pldoc/pull/8
Comments, discussion welcome!

Paulo Moura

unread,
May 22, 2015, 10:26:55 AM5/22/15
to Jan Wielemaker, Boris Vassilev, Julio Di Egidio, swi-p...@googlegroups.com
Although I agree that "++" and "--" are the best name choices, they do force the introduction of prefix operators *if* we want the mode directives to (also) be valid Prolog code :( Dreaming of the day where we can get rid of the limitations of ASCII.

Looking into these changes, the ISO spec (8.1.2.2), what I have in Logtalk itself, I'm still not happy with the mode indicator descriptions. Assume, for example, that a programmer wants to document a predicate, foo/1, that takes as *input* a variable. Which mode indicator should be used? "+" is usually interpreted as synonym of input argument but is described everywhere as meaning that the argument must be instantiated. "-" is usually interpreted as synonym of output argument (e.g. the ISO spec describes "-" as "the argument shall be a variable that will be instantiated iff the goal succeeds"). The new "--" could be used but *iff* the foo/1 predicate would not instantiate it. But "--" have an implicit meaning that will be used to return something. The best choice seems to be "@" but this says nothing about the predicate argument (non-)instantiation requirements.

Paulo Moura

unread,
May 22, 2015, 10:27:21 AM5/22/15
to Kilian Evang, swi-p...@googlegroups.com, boris.v...@gmail.com, ju...@diegidio.name

> On 22/05/2015, at 11:48, Kilian Evang <kilian...@gmail.com> wrote:
>
> I took a shot clarifying things further, pull request here: https://github.com/SWI-Prolog/packages-pldoc/pull/8
> Comments, discussion welcome!

Progress!

Cheers,

Paulo

> On Thursday, May 21, 2015 at 3:15:06 PM UTC+2, Jan Wielemaker wrote:
> On 05/21/2015 12:30 PM, Paulo Moura wrote:
> >>> In more formal mode system proposals we see `--` for that (and
> >>> `++` for ground).
> >>>
> >>> The `?` mode somehow affects the computation further than just
> >>> unifying the result when instantiated.
> >>>
> >>> Possibly we should add `--` to the documentation and document
> >>> their difference?
> >
> > That would indeed allow us to distinguish between the case above and
> > other cases such as open/3 where indeed the stream argument must be
> > unbound. As, as you mention, the cases where an argument must be
> > unbound are rare, it makes sense to introduce a new mode indicator
> > for these cases and keep using “-“ for the most common case where it
> > means*if* this argument is unbound,*then* expect this predicate
> > behavior.
>
> Added -- and ++ to PlDoc as well as the LaTeX based toolchain for
> generating the manuals. See [1], starting at line 19 for the
> updated description (this text is now repeated in the PlDoc
> manual).
>
> Thanks --- Jan
>
> [1] https://github.com/SWI-Prolog/swipl-devel/blob/master/man/builtin.doc

Jan Burse

unread,
May 23, 2015, 6:14:14 AM5/23/15
to swi-p...@googlegroups.com
Dear All,

Me lazy bugger, was using ++ and -- for a different purpose.
Assume a predicate has two different modes, i.e.:

:- mode append(+,+,-).
:- mode append(-,-,+).

I was lazily writing this as:

:- mode append(+-,+-,-+).

So basically argmodespec[i] was used for variant i of the
mode specification. Of course also ++ and -- can also happen.

Nevermind.

Bye

P.S.: I am using a different bootstrapping of aggregate_all/4, different
from SWI-Prolog which has a more complicated implementation, namely:

aggregate_all(A, T, G, R) :-
   findall(T, G, H),
   sort(H, L),
   aggregate_all(A, member(T, L), R).

Drawback, H is materialized. On the other hand, for modding the aggregate
predicates, it could be an other route in understanding the predicate and
or providing a different implemehtation.

Warning: There is a small chance that the above bootstrapping variant is
not correct. Did not yet develop some test case. Also did't find some tests
for these predicates in Pualo Mouras test suite.

Kilian Evang

unread,
May 23, 2015, 7:08:01 AM5/23/15
to swi-p...@googlegroups.com
On Saturday, May 23, 2015 at 12:14:14 PM UTC+2, Jan Burse wrote:
P.S.: I am using a different bootstrapping of aggregate_all/4, different
from SWI-Prolog which has a more complicated implementation, namely:

aggregate_all(A, T, G, R) :-
   findall(T, G, H),
   sort(H, L),
   aggregate_all(A, member(T, L), R).

Drawback, H is materialized. On the other hand, for modding the aggregate
predicates, it could be an other route in understanding the predicate and
or providing a different implemehtation.

Warning: There is a small chance that the above bootstrapping variant is
not correct. Did not yet develop some test case. Also did't find some tests
for these predicates in Pualo Mouras test suite.

I think this won't work if T (the discriminator) does not also contain all the variables that appear in A (the template).

For example:

?- listing(country/2).
':- dynamic country/2.

country(belgium, 11000000).
country(belgium, 11000000).

true.

?- aggregate_all(sum(P), Name, country(Name, P), Total).
Total = 11000000.

?- ?- aggregate_all_jan(sum(P), Name, country(Name, P), Total).
ERROR: is/2: Arguments are not sufficiently instantiated
?- aggregate_all_jan(sum(P), Name-P, country(Name, P), Total).
Total = 11000000.

Julio Di Egidio

unread,
May 23, 2015, 1:53:07 PM5/23/15
to swi-p...@googlegroups.com
On Thursday, May 21, 2015 at 11:30:13 AM UTC+1, Paulo Moura wrote:
> On 20/05/2015, at 18:21, Jan Wielemaker <J.Wiel...@vu.nl> wrote:
>
> On 05/20/2015 06:37 PM, Boris Vassilev wrote:
>> One needs a lot of implicit knowledge to read the SWI-Prolog
>> documentation, or any Prolog implementation documentation, or any
>> documentation, or any text, for that matter (and so on).
>>
>> The issue of -R vs ?R confused me too once (I tried to dig up the
>> conversation with Jan but I don't remember the context, so I couldn't
>> find it).
>>
>> Would it be worth the effort to shortly discuss the issue in the
>> documentation of PlDoc?
>>
>> http://www.swi-prolog.org/pldoc/man?section=modes
>>
>> If I remember correctly, the original source of my confusion was:
>>
>> Instantiation patterns are:
>> ...
>> - : argument must be unbound
>> …

*must* is the misleading bit. When used in predicate templates, we want to tell the programmer what is to be *expected* *when* the argument is unbound. Predicates can have multiple templates and behave differently (e.g. regarding the number of solutions) when an argument is bound or unbound.

Consider as an example the specification of the standard atom_concat/3 predicate:

atom_concat(?atom, ?atom, +atom)
atom_concat(+atom, +atom, -atom)

In the second template, we’re *not* specifying that the third argument must be unbound when the first two argument are bound (that would conflict with the first template!). If we couple these template and modes specs with determinism information, we’re providing useful information to the programmer. In this case, that calls using the second template will succeed deterministically.

There is a serious problem with that approach: a programmer using some Prolog system needs to know *exactly* what to expect, so we need a _normative_ spec, not a spec that tells what happens in some cases but leaves undefined other cases, which we shall rather dub _incomplete_.  Indeed, a programmer given an incomplete spec is *expected* either to code defensively or to ignore any modes that are not exactly defined, so that, even if now in the form of working-around and/or wrapping, we are anyway back to a *normative* approach. -- That might not be such an important distinction for academic research, it is a must for production.

>> I still think it is better to leave things as they are, but explaining
>> this "gotcha" might be helpful.
>
> I agree.  The above should be fixed.  The mode `-` as "argument must be
> unbound"
> is pretty meaningless as there are probably not more than a handful of
> predicates
> for which this applies.

I would not agree here either, but this too much depends on one's stance re the point above...
 
Julio

--
Please do not CC me in, just reply to the group.

Paulo Moura

unread,
May 23, 2015, 3:13:41 PM5/23/15
to GoogleSWI-Prolog

> On 23/05/2015, at 18:53, Julio Di Egidio <ju...@diegidio.name> wrote:
>
> On Thursday, May 21, 2015 at 11:30:13 AM UTC+1, Paulo Moura wrote:
> > On 20/05/2015, at 18:21, Jan Wielemaker <J.Wiel...@vu.nl> wrote:
> >
> > On 05/20/2015 06:37 PM, Boris Vassilev wrote:
> >> One needs a lot of implicit knowledge to read the SWI-Prolog
> >> documentation, or any Prolog implementation documentation, or any
> >> documentation, or any text, for that matter (and so on).
> >>
> >> The issue of -R vs ?R confused me too once (I tried to dig up the
> >> conversation with Jan but I don't remember the context, so I couldn't
> >> find it).
> >>
> >> Would it be worth the effort to shortly discuss the issue in the
> >> documentation of PlDoc?
> >>
> >> http://www.swi-prolog.org/pldoc/man?section=modes
> >>
> >> If I remember correctly, the original source of my confusion was:
> >>
> >> Instantiation patterns are:
> >> ...
> >> - : argument must be unbound
> >> …
>
> *must* is the misleading bit. When used in predicate templates, we want to tell the programmer what is to be *expected* *when* the argument is unbound. Predicates can have multiple templates and behave differently (e.g. regarding the number of solutions) when an argument is bound or unbound.
>
> Consider as an example the specification of the standard atom_concat/3 predicate:
>
> atom_concat(?atom, ?atom, +atom)
> atom_concat(+atom, +atom, -atom)
>
> In the second template, we’re *not* specifying that the third argument must be unbound when the first two argument are bound (that would conflict with the first template!). If we couple these template and modes specs with determinism information, we’re providing useful information to the programmer. In this case, that calls using the second template will succeed deterministically.
>
>> There is a serious problem with that approach: a programmer using some Prolog system needs to know *exactly* what to expect, so we need a _normative_ spec, not a spec that tells what happens in some cases but leaves undefined other cases, which we shall rather dub _incomplete_.

Why do you think that the other cases are left unspecified? The two templates above for the atom_concat/3 predicate are copied verbatim from the ISO standard but they are just *part* of the specification of the predicate. That specification also details what happens when the arguments fall outside these templates (in the "Errors" section).

It's also worth noting that most predicates, both standard and user-defined, are only meaningful for a small set of (mode&type) templates. Not covered templates usually result in either error or failures but that should also be part of the predicate specification.

>> Indeed, a programmer given an incomplete spec is *expected* either to code defensively or to ignore any modes that are not exactly defined, so that, even if now in the form of working-around and/or wrapping, we are anyway back to a *normative* approach. -- That might not be such an important distinction for academic research, it is a must for production.

The ISO standard provides a good model on how to document a predicate. I follow that model in Logtalk. Same for several Prolog systems. Others may not be there yet but I'm sure their developers welcome patches to improve predicate documentation.

> >> I still think it is better to leave things as they are, but explaining
> >> this "gotcha" might be helpful.
> >
> > I agree. The above should be fixed. The mode `-` as "argument must be
> > unbound"
> > is pretty meaningless as there are probably not more than a handful of
> > predicates
> > for which this applies.
>
> I would not agree here either, but this too much depends on one's stance re the point above...

Note that most predicates specifying a argument as "-" can be called with that argument bound. But, as others remarked already in this discussion, that may change the number of solutions of a predicate. Worse, if the predicate type-checks output arguments, you can get an error while you would get instead a failure if the unification is done after the predicate call (e.g. setof(X, foo(X), [1|a]) vs setof(X, foo(X), L), L = [1|a]). That's the main reason why some predicates (such as atom_concat/3) have two or more templates, as that allows the exact specification of what is expected in each case. But the problem here is documentation and how the user interprets that documentation. Using again atom_concat/3 as an example, the template

atom_concat(+atom, +atom, -atom)

doesn't make a call such as:

atom_concat(a, b, ab)

illegal as we also have the template

atom_concat(?atom, ?atom, +atom)

which covers it. Thus "-" meaning "argument MUST be unbound" must be interpreted in the context of the template where it's used, not as meaning that the predicate cannot be called with that argument bound (unless there's a single template). But this should be explained in the section about argument modes. Kilian's proposed patch is step in that direction.

A good example of a predicate with a single template where "-" is used is open/3:

open(@source_sink, @io_mode, -stream)

calling this predicate with its third argument bound is specified as resulting in a type_error(variable, Culprit) (revised to uninstantiation_error(Culprit) in a recent ISO spec revision). But the issue here is different from e.g. the use of "-" in atom_concat/3: stream handles are often opaque terms, making it essentially meaningless to call open/3 with the stream argument bound. The idea of introducing a "--" mode is to help distinguish these cases.

Jan Burse

unread,
May 24, 2015, 5:33:39 AM5/24/15
to swi-p...@googlegroups.com
Aha, Ok. Thanks for sharing. Have to check.

Julio Di Egidio

unread,
May 24, 2015, 10:56:36 AM5/24/15
to swi-p...@googlegroups.com
On Saturday, May 23, 2015 at 8:13:41 PM UTC+1, Paulo Moura wrote:
> On 23/05/2015, at 18:53, Julio Di Egidio <ju...@diegidio.name> wrote:
> On Thursday, May 21, 2015 at 11:30:13 AM UTC+1, Paulo Moura wrote: 
 
> *must* is the misleading bit. When used in predicate templates, we want to tell the programmer what is to be *expected* *when* the argument is unbound. Predicates can have multiple templates and behave differently (e.g. regarding the number of solutions) when an argument is bound or unbound.
>
> Consider as an example the specification of the standard atom_concat/3 predicate:
>
> atom_concat(?atom, ?atom, +atom)
> atom_concat(+atom, +atom, -atom)
>
> In the second template, we’re *not* specifying that the third argument must be unbound when the first two argument are bound (that would conflict with the first template!). If we couple these template and modes specs with determinism information, we’re providing useful information to the programmer. In this case, that calls using the second template will succeed deterministically.
>
>> There is a serious problem with that approach: a programmer using some Prolog system needs to know *exactly* what to expect, so we need a _normative_ spec, not a spec that tells what happens in some cases but leaves undefined other cases, which we shall rather dub _incomplete_.

Why do you think that the other cases are left unspecified? The two templates above for the atom_concat/3 predicate are copied verbatim from the ISO standard but they are just *part* of the specification of the predicate. That specification also details what happens when the arguments fall outside these templates (in the "Errors" section).

You have not specified the determinism, so those are indeed not satisfactory in the context of this discussion...  But that is beside my point: it is to your "*must* is the misleading bit" that I am objecting: and discussing specific solutions to a putative problem with the docs has to start from the agreement on that fundamental principle, i.e. that notions in a reference documentation must be expressed in terms of *must be*, not in terms of *can be*.  Do you agree on that?  You seem all for it in this post, but given the above I had and still have to ask.

It's also worth noting that most predicates, both standard and user-defined, are only meaningful for a small set of (mode&type) templates. Not covered templates usually result in either error or failures but that should also be part of the predicate specification.

A predicate specification shall be "complete" is what I am saying, indeed it goes together with a must be approach.

>>  Indeed, a programmer given an incomplete spec is *expected* either to code defensively or to ignore any modes that are not exactly defined, so that, even if now in the form of working-around and/or wrapping, we are anyway back to a *normative* approach. -- That might not be such an important distinction for academic research, it is a must for production.

The ISO standard provides a good model on how to document a predicate. I follow that model in Logtalk. Same for several Prolog systems. Others may not be there yet but I'm sure their developers welcome patches to improve predicate documentation.
<snip>

So you are now telling me that there is no problem at all, "just follow the standard", yet you were advocating the introduction of a new "mode indicator"??
 
> >> I still think it is better to leave things as they are, but explaining
> >> this "gotcha" might be helpful.
> >
> > I agree.  The above should be fixed.  The mode `-` as "argument must be
> > unbound"
> > is pretty meaningless as there are probably not more than a handful of
> > predicates
> > for which this applies.
>
> I would not agree here either, but this too much depends on one's stance re the point above...

Note that most predicates specifying a argument as "-" can be called with that argument bound. But, as others remarked already in this discussion, that may change the number of solutions of a predicate.

For the chronicle, "-" to me rather naturally reads: the predicate behaves in a certain way when the arg is var (unbound), so if one gives a nonvar argument, *that is equivalent to* first invoking the predicate, then performing the unification.
 
Worse, if the predicate type-checks output arguments
<snip>

With the semantics I have mentioned above, one could simply establish (in order indeed to allow the short-cut) that a predicate will *not* check output (i.e. "-") arguments.  But I would insist that we first explicitly agree on the *must be* vs. *can be* principle, IMO there is just no point in discussing solutions to a problem that has not yet been clearly stated.

Julio

Julio Di Egidio

unread,
May 24, 2015, 12:25:27 PM5/24/15
to swi-p...@googlegroups.com
Sorry, right example, but the whole argument is backwards: please scratch that and let me rephrase:

Not checking that the argument is unbound and still working correctly if it is not requires careful coding of a predicate (usually just make sure the output argument does not get bound until the very end), so again I would rather approach this with "?" argument when that invocation pattern is supported, and with "-" otherwise.  And we are back to usual type checking and all...

[But the "must be" over "can be" approach for reference documentation remains: I shall just assume you agree unless you say otherwise.]

Julio

Kilian Evang

unread,
May 24, 2015, 12:51:54 PM5/24/15
to swi-p...@googlegroups.com
On Sunday, May 24, 2015 at 4:56:36 PM UTC+2, Julio Di Egidio wrote:
On Saturday, May 23, 2015 at 8:13:41 PM UTC+1, Paulo Moura wrote:
> On 23/05/2015, at 18:53, Julio Di Egidio <ju...@diegidio.name> wrote:
> On Thursday, May 21, 2015 at 11:30:13 AM UTC+1, Paulo Moura wrote: 
 
> *must* is the misleading bit. When used in predicate templates, we want to tell the programmer what is to be *expected* *when* the argument is unbound. Predicates can have multiple templates and behave differently (e.g. regarding the number of solutions) when an argument is bound or unbound.
>
> Consider as an example the specification of the standard atom_concat/3 predicate:
>
> atom_concat(?atom, ?atom, +atom)
> atom_concat(+atom, +atom, -atom)
>
> In the second template, we’re *not* specifying that the third argument must be unbound when the first two argument are bound (that would conflict with the first template!). If we couple these template and modes specs with determinism information, we’re providing useful information to the programmer. In this case, that calls using the second template will succeed deterministically.
>
>> There is a serious problem with that approach: a programmer using some Prolog system needs to know *exactly* what to expect, so we need a _normative_ spec, not a spec that tells what happens in some cases but leaves undefined other cases, which we shall rather dub _incomplete_.

Why do you think that the other cases are left unspecified? The two templates above for the atom_concat/3 predicate are copied verbatim from the ISO standard but they are just *part* of the specification of the predicate. That specification also details what happens when the arguments fall outside these templates (in the "Errors" section).

(...) it is to your "*must* is the misleading bit" that I am objecting: and discussing specific solutions to a putative problem with the docs has to start from the agreement on that fundamental principle, i.e. that notions in a reference documentation must be expressed in terms of *must be*, not in terms of *can be*.

I think a reference documentation should be *descriptive*: if you do X, then Y will happen. The emerging practice with PlDoc for SWI-Prolog, as I see it, fits this pattern: each template in a predicate documentation describes a particular set of goals, and each template contains additional information about what to expect when calling one of these goals – in particular, information about determinism, and some information about steadfastness and whether arguments will be further bound.

As for "incomplete spec": if a particular goal does not fit any of the templates, then that is PlDoc's way of telling you that you should not be calling that goal and warning you that undefined behavior would result.

I tried to capture this in my proposal for updating the documentation: https://github.com/texttheater/packages-pldoc/commit/d56bc5174c4548efcd73d109a98aab3a4d51aac6

Does this address your objection?

Julio Di Egidio

unread,
May 24, 2015, 1:12:36 PM5/24/15
to swi-p...@googlegroups.com
On Sunday, May 24, 2015 at 5:51:54 PM UTC+1, Kilian Evang wrote:
On Sunday, May 24, 2015 at 4:56:36 PM UTC+2, Julio Di Egidio wrote:
On Saturday, May 23, 2015 at 8:13:41 PM UTC+1, Paulo Moura wrote:
> On 23/05/2015, at 18:53, Julio Di Egidio <ju...@diegidio.name> wrote: 
(...) it is to your "*must* is the misleading bit" that I am objecting: and discussing specific solutions to a putative problem with the docs has to start from the agreement on that fundamental principle, i.e. that notions in a reference documentation must be expressed in terms of *must be*, not in terms of *can be*.

I think a reference documentation should be *descriptive*

No, a *reference* documentation is _normative_, *guides* are _descriptive_: and, to be clear, this is long standing technical terminology and notions, not my invention.

As for "incomplete spec": if a particular goal does not fit any of the templates, then that is PlDoc's way of telling you that you should not be calling that goal and warning you that undefined behavior would result.

The point remains that we need a _complete_ spec, and your idea here rather is an example of how to get that in a very simple way that does not have to rely on the programmer covering all cases.  But not only the point remains that we are in need of a _complete_ spec, and if there is any disagreement (at least so far) it seems it just boils down to some terminological confusion, the issue here really is not about how to write a proper spec of some predicate (a problem of content), but the more basic issue of whether the (documentation) language itself supports writing complete and unambiguous specs to begin with.

Julio

Boris Vassilev

unread,
May 24, 2015, 1:52:24 PM5/24/15
to swi-p...@googlegroups.com
Hello Julio,

On Sun, May 24, 2015 at 8:12 PM, Julio Di Egidio <ju...@diegidio.name> wrote:
The point remains that we need a _complete_ spec, and your idea here rather is an example of how to get that in a very simple way that does not have to rely on the programmer covering all cases.  But not only the point remains that we are in need of a _complete_ spec, and if there is any disagreement (at least so far) it seems it just boils down to some terminological confusion, the issue here really is not about how to write a proper spec of some predicate (a problem of content), but the more basic issue of whether the (documentation) language itself supports writing complete and unambiguous specs to begin with.

I hope that my attempt at explanation is not a waste of your time. First off, instantiation patterns, executive summary:

`foo(?A, ?B)` usually means that calling `foo/2` with A instantiated will give you solutions for B, and with B instantiated solutions for A. In some cases, you can leave both A and B free and still get meaningful solutions (Ex: length/2). In other cases, two out of three argument must be instantiated (Ex: plus/3). These details are currently quite faithfully documented.

In comparison: `bar(+A, -B)` means that calling `bar/2` with A instantiated will give solutions for B. If B is (partially) instantiated, and the solution cannot be unified with it, it *will fail*. If it can be unified, B will be fully instantiated when the predicate succeeds.

There are some cases when it is actually necessary to have a free variable (see previous emails in this thread). For those rare cases, it was suggested to have `--` as an instantiation pattern.

And now to your point about a "complete spec": The source is the complete spec. It is waiting out there for someone to read it. If you actually did have a *complete* spec, it would necessarily have to mirror the implementation *exactly*. So, assuming that the reader has some idea about Prolog's execution model, a predicate documentation tries to be pragmatic. It offer a human with the most important things there are to know about when to use a predicate and what to expect from it under the intended use. Anyway, this is *the best* you can hope for when you use a natural language.

You can go ahead and come up with a formal language that can completely specify the behaviour of a predicate in all possible instantiations. I just wonder why would anyone want to do that, when the (Prolog) implementation does it already.

Kilian Evang

unread,
May 24, 2015, 2:01:54 PM5/24/15
to swi-p...@googlegroups.com
On Sunday, May 24, 2015 at 7:12:36 PM UTC+2, Julio Di Egidio wrote:
On Sunday, May 24, 2015 at 5:51:54 PM UTC+1, Kilian Evang wrote:
On Sunday, May 24, 2015 at 4:56:36 PM UTC+2, Julio Di Egidio wrote:
On Saturday, May 23, 2015 at 8:13:41 PM UTC+1, Paulo Moura wrote:
> On 23/05/2015, at 18:53, Julio Di Egidio <ju...@diegidio.name> wrote: 
(...) it is to your "*must* is the misleading bit" that I am objecting: and discussing specific solutions to a putative problem with the docs has to start from the agreement on that fundamental principle, i.e. that notions in a reference documentation must be expressed in terms of *must be*, not in terms of *can be*.

I think a reference documentation should be *descriptive*

No, a *reference* documentation is _normative_, *guides* are _descriptive_: and, to be clear, this is long standing technical terminology and notions, not my invention.

As for "incomplete spec": if a particular goal does not fit any of the templates, then that is PlDoc's way of telling you that you should not be calling that goal and warning you that undefined behavior would result.

The point remains that we need a _complete_ spec, and your idea here rather is an example of how to get that in a very simple way that does not have to rely on the programmer covering all cases.

I don't think it's my idea, it just hadn't been written down explicitly so far.
 
  if there is any disagreement (at least so far) it seems it just boils down to some terminological confusion

I agree.
 
, the issue here really is not about how to write a proper spec of some predicate (a problem of content), but the more basic issue of whether the (documentation) language itself supports writing complete and unambiguous specs to begin with.

I think PlDoc does support that, at least if I interpreted according to my proposal.

That's not to say it couldn't be improved. For example, I find it confusing that some argument instantiation patterns describe the goal (++, +, :, -, --, ?) and some describe the behavior of the predicate when that goal is called (-, :, @, !).

Julio Di Egidio

unread,
May 24, 2015, 2:02:09 PM5/24/15
to swi-p...@googlegroups.com
I won't go through the details of your post, the objections would be the same: just, please, at least note that I am *not* the one who is proposing changes to the *documentation language*...

Julio

Jan Wielemaker

unread,
May 25, 2015, 4:08:54 AM5/25/15
to Julio Di Egidio, swi-p...@googlegroups.com
On 05/24/2015 07:12 PM, Julio Di Egidio wrote:
> The point remains that we need a _complete_ spec, and your idea here
> rather is an example of how to get that in a very simple way that does
> not have to rely on the programmer covering all cases. But not only the
> point remains that we are in need of a _complete_ spec, and if there is
> any disagreement (at least so far) it seems it just boils down to some
> terminological confusion, the issue here really is not about how to
> write a proper spec of some predicate (a problem of content), but the
> more basic issue of whether the (documentation) language itself supports
> writing complete and unambiguous specs to begin with.

As I see it, Prolog is a dynamically typed language that has no formal
type, mode and determinism component. Without that formal component,
implementations can try to find the most sensible/logical/... way to
interpret the arguments. That is what happens, in the standard,
implementation extensions as well as in applications.

Mercury for example has a formal type, mode and determinism
annotation. Mercury cannot implement all the usual Prolog predicates
with the usually seen mode/type/determinism (AFAIK).

As a result, the specification is the combination of a informative
type/mode/determinsm annotation system and the subsequent text. The
combination should (in theory) be complete. I sympathise with Boris
that the implementation is the final spec, but I do also disagree: we
want to be able to modify the implementation for
clarity/performance/... reason. It is pretty unlikely that the new
implementation will be 100% compatible with the old, generally this is
only the case within a restricted domain.

Anyway, we are miles away from a complete documentation in the above
sense for SWI-Prolog. I don't really see a way to get there either
... As is, it are mostly rather concise descriptions that need some
interpretation. Best we can probably do is to streamline the feedback
loop and improve documentation that is apparently too vague.

Cheers --- Jan

Jan Wielemaker

unread,
May 25, 2015, 5:27:25 AM5/25/15
to Anne Ogborn, Paulo Moura, Julio Di Egidio, swi-p...@googlegroups.com
I think it would be a great and probably the only feasible way to
get the documentation improved by the users. That said, given the
current way the documentation is generated, this won't be easy. For
the PlDoc comments it might not be too hard:

- Pick the comment block for the predicate (that is available
in the server's database).
- Dump it in the already present PlDoc web editor
- Submit as a proposal for review.

It will be a lot trickier for the LaTeX based documentation :-)

Cheers --- Jan

Kilian Evang

unread,
May 25, 2015, 5:59:48 AM5/25/15
to swi-p...@googlegroups.com, pjlm...@gmail.com, an...@theelginworks.com, ju...@diegidio.name

GitHub allows users to edit (and then propose for merge) text files in the browser. We could have automatically generated "Edit" buttons througout the documentation, linking to URLs like these:

https://github.com/SWI-Prolog/packages-pldoc/edit/master/pldoc.doc (for doc pages)
https://github.com/SWI-Prolog/swipl-devel/edit/master/library/aggregate.pl (for modules)

Jan Wielemaker

unread,
May 25, 2015, 4:03:54 PM5/25/15
to Paulo Moura, Boris Vassilev, Julio Di Egidio, swi-p...@googlegroups.com
On 05/22/2015 04:26 PM, Paulo Moura wrote:

> Although I agree that "++" and "--" are the best name choices, they
> do force the introduction of prefix operators *if* we want the mode
> directives to (also) be valid Prolog code :( Dreaming of the day
> where we can get rid of the limitations of ASCII.

That is also the case for ?, @ and :. It is no issue for SWI-Prolog
as PlDoc comments are Prolog comments. The %! (%%) line has formal
syntax, but is parsed using the operators defined in doc_modes.pl

> Looking into these changes, the ISO spec (8.1.2.2), what I have in
> Logtalk itself, I'm still not happy with the mode indicator
> descriptions. Assume, for example, that a programmer wants to
> document a predicate, foo/1, that takes as *input* a variable. Which
> mode indicator should be used? "+" is usually interpreted as synonym
> of input argument but is described everywhere as meaning that the
> argument must be instantiated. "-" is usually interpreted as synonym
> of output argument (e.g. the ISO spec describes "-" as "the argument
> shall be a variable that will be instantiated iff the goal
> succeeds"). The new "--" could be used but *iff* the foo/1 predicate
> would not instantiate it. But "--" have an implicit meaning that will
> be used to return something. The best choice seems to be "@" but this
> says nothing about the predicate argument (non-)instantiation
> requirements.

I guess that is true. On the other hand, what is sensible example of
a predicate taking a variable input and not unifying it with anything?
Maybe it is late, but I can't think of anything ...

Cheers --- Jan

Julio Di Egidio

unread,
May 25, 2015, 5:19:43 PM5/25/15
to swi-p...@googlegroups.com, boris.v...@gmail.com, pjlm...@gmail.com, ju...@diegidio.name
Of course that would be true in 99% of the cases...

Guys, as far as what is expected from a spec, the issue is not what the user is going to do, the issue is whether a programmer can document *what the predicate supports*.  And I'll remind you of my previous example: supporting '?' (in the literal sense of "any arg binding allowed") requires *extra logic* than supporting '-' (in the iteral sense of "only arg unbound allowed").  To take the initial case as an example, aggregate_all turns out to be semidet with ?R, or one could be *sharper* and say it is det with -R and semidet with +R: IOW, it is just a bug in the documentation, unfortunately affecting most of the predicates whose intrinsic mode is '?' rather than just '-' (still in the sense above).  Then, I am not saying the doc language could not be extended to allow for even *sharper* definitions, but that would be a further step: in the meantime the docs are simply broken, IMHO...

Julio

Paulo Moura

unread,
May 25, 2015, 5:20:51 PM5/25/15
to Jan Wielemaker, Boris Vassilev, Julio Di Egidio, swi-p...@googlegroups.com

Julio Di Egidio

unread,
May 25, 2015, 5:32:14 PM5/25/15
to swi-p...@googlegroups.com
Along the same line of specifying functionality not usage, note that the specifiers are meant to indicate instantiation patterns, not any input/output patterns...

Julio

P.S.  Quite annoying these automatic CC-ing: I am stripping CCs whenever I remember...  Is it maybe good etiquette for the group that I CC everybody involved or is it just courtesy Google Groups?

Samer Abdallah

unread,
May 25, 2015, 5:33:54 PM5/25/15
to <swi-prolog@googlegroups.com>

On 25 May 2015, at 21:03, Jan Wielemaker <J.Wiel...@vu.nl>
wrote:

>> Looking into these changes, the ISO spec (8.1.2.2), what I have in
>> Logtalk itself, I'm still not happy with the mode indicator
>> descriptions. Assume, for example, that a programmer wants to
>> document a predicate, foo/1, that takes as *input* a variable. Which
>> mode indicator should be used? "+" is usually interpreted as synonym
>> of input argument but is described everywhere as meaning that the
>> argument must be instantiated. "-" is usually interpreted as synonym
>> of output argument (e.g. the ISO spec describes "-" as "the argument
>> shall be a variable that will be instantiated iff the goal
>> succeeds"). The new "--" could be used but *iff* the foo/1 predicate
>> would not instantiate it. But "--" have an implicit meaning that will
>> be used to return something. The best choice seems to be "@" but this
>> says nothing about the predicate argument (non-)instantiation
>> requirements.
>
> I guess that is true. On the other hand, what is sensible example of
> a predicate taking a variable input and not unifying it with anything?
> Maybe it is late, but I can't think of anything …

Forgive me if I've got the wrong end of the stick, but surely the first argument
of findall/3, bagof/3 etc is like this? It seems to play the role of a formal
parameter, or bound variable. Another example is B-Prolog's maplist, which
works like this:

?- maplist(X,Y,Y is X+1,[1,2,3],Z).
Z = [2,3,4]

Similarly, with_stream/3 in the 'fileutils' pack:

with_stream(S, <any goal to open stream as S>, <goal using S>)

e.g.

?- with_stream(S, open(pipe(say),write,S), writeln(S,hello)).

S remains unbound on exit as it's purpose is not to return a stream handle,
but as a place marker. We would not really want the stream handle to leak
out anyway. Perhaps it would be better to write this as

with_stream_alt( Open, Pred) :-
setup_call_cleanup( call(Open,S), call(Pred,S), close(S)).

and force the use of an auxilliary predicate or explicit lambda
?- use_module(library(lambda)).
?- with_stream( open(pipe(say),\S^writeln(S,hello)).

but then again, S is a variable that remains unbound on exit.

Samer

>
> Cheers --- Jan
>
> --
> You received this message because you are subscribed to the Google Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to swi-prolog+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/swi-prolog.
> For more options, visit https://groups.google.com/d/optout.

signature.asc

Paulo Moura

unread,
May 25, 2015, 6:19:36 PM5/25/15