?- findall(_,fail,L).
L = [].
?- aggregate_all(count,fail,C).
C = 0.
?- aggregate_all(c,fail,C).
ERROR: Type error: `aggregate_template' expected, found `c'
?- 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.
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_
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.
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?
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`
--
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.
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).
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
aggregate_all(A, T, G, R) :- findall(T, G, H), sort(H, L), aggregate_all(A, member(T, L), R).
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.
> 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.
> 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'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
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*.
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*
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.
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.
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.
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...
On 05/26/2015 10:05 AM, Kilian Evang wrote:
> I also think that the convention itself is confusing and maybe not ideal.
It is annoying that the SWI-Prolog documentation is in this sense not
compatible with the ISO docs. The ISO templates do not include
determinism information. As I claim in my previous mail, ? may be
correct (it is always correct as it claims nothing), but there are
many forms of `?` and thus you loose a lot of meaningful information.
Seriously, you started a discussion that engaged people to spend valuable time participating. True, you may find progress slow, sometimes with wrong turns, but loosing patience and being harsh just puts *you* out of the equation.
> On 26/05/2015, at 18:09, Jan Wielemaker <J.Wiel...@vu.nl> wrote:
> In most cases, the SWI-Prolog docs try to reduce to a single template
> line. Some of that is due to old days when there was no support for
> multiple template lines. I still think that if it can be done in an
> understandable way with a single template, that is enough. Less
> documentation is better, but of course it must be sufficient.
It's a pragmatic choice.
On Wednesday, May 27, 2015 at 12:51:18 AM UTC+1, Paulo Moura wrote:> On 26/05/2015, at 18:09, Jan Wielemaker <J.Wiel...@vu.nl> wrote:<snip>> In most cases, the SWI-Prolog docs try to reduce to a single template
> line. Some of that is due to old days when there was no support for
> multiple template lines. I still think that if it can be done in an
> understandable way with a single template, that is enough. Less
> documentation is better, but of course it must be sufficient.
It's a pragmatic choice.It is simply broken, you just cannot compromise on correctness. And, instead of fixing it, you are simply making it more convoluted...
On 05/27/2015 10:04 AM, Julio Di Egidio wrote:
<snip>
> To be clear, already a philosophy such as "some implicit knowledge is
> unavoidable" is *broken*.
>
> To me fixing that is the base line: missing that, there is indeed no
> point in looking into this matter any further (the horse is dead already).
I'm going to summarize:
- The notation used by SWI-Prolog is closely related to other
major Prolog systems (checked SICSTus, YAP and ECLiPSe).
- The definition of a predicate consists of a formal part and
and informal description.
- The formal template consist of mode, type and determinism
information.
- The current system is quite accurately described by me and
Killian, thanks to this discussion.
I'm pretty sure we
can actually create a formal definition, but I'm too lazy
for that.
That said, there are some remarks on the way the documentation
system is used:
- Type information is in most cases lacking from the formal
part. That is a pity, especially because it is unclear what
`+` means if the type is unknown.
- Quite a few templates over generalize. I think that is fine
as long as the intend is rather obvious and the description
states what is going on. For example, we can have
atom_codes(?Atom, ?Codes) is det.
There is quite some implicit information in there, but anyone
with basic knowledge will understand this boils down to this
(-,+ uses as instantiated).
atom_codes(-,-) --> instantiation error
atom_codes(+,-) --> det.
atom_codes(-,+) --> det.
atom_codes(+,+) --> semidet.
Note the value of this in auto-completion as used by SWISH
(go to http://swish.swi-prolog.org, type "atom" and hit
Control-space)
- Some templates are simply wrong. These should be reported
and fixed. I first though you were correct about aggregate_all,
but it turned out to be more complicates as your claim was for
an incorrect interpretation of the poorly documented template
notation and as Killian pointed out, these are really semidet.
This is the end of this discussion for me, unless someone comes
with a really nice proposal and a plan to realise the required
code changes to the documentation system and revise the existing
docs.
On 05/27/2015 11:08 AM, Julio Di Egidio wrote:
> Where is that description? I am certainly interested.
https://github.com/SWI-Prolog/packages-pldoc/blob/master/pldoc.doc,
table starting at line 244.
> I had suggested that
> aggregate_all/3 could be declared (+T,:G,?R) semidet and the bug was
> already solved (covering the differences between templates already).
`(+T,:G,?R) semidet` is correct, but so is `(+T,:G,-R) semidet` and
it is more specific and conveys the intended use much better. It says
"the predicate computes a value for R and unifies that with the
argument", as well as "the value computed for R does not depend
on a possible (partial) instantiation of this argument".
That is both pretty useful information.
Where is that description? I am certainly interested.
both you and Killian have simply missed my point all along: in particular, I had suggested that aggregate_all/3 could be declared (+T,:G,?R) semidet
and the bug was already solved (covering the differences between templates already).
> Where is that description? I am certainly interested.
https://github.com/SWI-Prolog/packages-pldoc/blob/master/pldoc.doc,
table starting at line 244.You have introduced the notion of types into it: and I am depressed...
I have to bet it will bite back in the (not so) long run, as it is in violation of two principle already, correctness and no implicit knowledge
On Wednesday, May 27, 2015 at 11:37:21 AM UTC+2, Julio Di Egidio wrote:> Where is that description? I am certainly interested.
https://github.com/SWI-Prolog/packages-pldoc/blob/master/pldoc.doc,
table starting at line 244.You have introduced the notion of types into it: and I am depressed...
It has been there for ages.
I have to bet it will bite back in the (not so) long run, as it is in violation of two principle already, correctness and no implicit knowledge
You have a very funny notion of "correctness". To you, "correct" apparently means: "- stands for 'unbound at call-time'". Therefore, any system in which - stands for something else, is incorrect.
On Wednesday, May 27, 2015 at 10:53:29 AM UTC+1, Jan Wielemaker wrote:
Prolog programs, you need to combine instantiation, types and
determinism.
I try to copy good ideas instead of inventing poor ones.
On Wednesday, May 27, 2015 at 10:48:46 AM UTC+1, Kilian Evang wrote:On Wednesday, May 27, 2015 at 11:37:21 AM UTC+2, Julio Di Egidio wrote:> Where is that description? I am certainly interested.
https://github.com/SWI-Prolog/packages-pldoc/blob/master/pldoc.doc,
table starting at line 244.You have introduced the notion of types into it: and I am depressed...
It has been there for ages.My bad for not noticing it before...